Я использую функцию Azure для приема сообщений из концентратора событий и отправки уведомлений через концентратор уведомлений Azure. Работает отлично! Теперь я хотел посмотреть, могу ли я добавлять теги к этим сообщениям, чтобы разрешить пользователям таргетинг с помощью этих тегов.
Выходные данные для концентратора уведомлений имеют параметр «выражение тега», который вы можете настроить. Но это похоже на статичный текст. Вместо этого мне нужно динамически устанавливать эти теги на основе сообщения, полученного от концентратора событий. Я не уверен, можно ли как-нибудь поместить туда динамический контент?
Я также обнаружил, что конструктор объекта GcmNotification, который я использую, имеет перегрузку, которая позволяет использовать строку тега. Но когда я пытаюсь это сделать, я получаю предупреждение во время компиляции о том, что это устарело, и когда функция запускается, она показывает ошибку, потому что свойство Tag должно быть пустым.
Так что я не понимаю, а) возможно ли это вообще и б) как это сделать, когда это возможно. Любые идеи?
Обновление: как было предложено, я попытался создать объект POCO для сопоставления с моей входной строкой. Строка выглядит следующим образом:
[{"deviceid":"repsaj-neptune-win10pi","readingtype":"temperature1","reading":22.031614503139451,"threshold":23.0,"time":"2016-06-22T09:38:54.1900000Z"}]
Объект POCO:
public class RuleMessage
{
public string deviceid;
public string readingtype;
public object reading;
public double threshold;
public DateTime time;
}
Для функции я теперь попробовал как RuleMessage[]
, так и List<RuleMessage>
в качестве типов параметров, но функция жалуется, что не может преобразовать ввод:
2016-06-24T18: 25: 16.830 Исключение при выполнении функции: Functions.submerged-function-ruleout. Microsoft.Azure.WebJobs.Host: параметр привязки исключения 'inputMessage'. Microsoft.Azure.WebJobs.Host: параметры привязки к сложным объектам (например, «RuleMessage») используют сериализацию Json.NET. 1. Свяжите тип параметра как «строка» вместо «RuleMessage», чтобы получить необработанные значения и избежать десериализации JSON, или 2. Измените полезную нагрузку очереди на допустимый json. Ошибка синтаксического анализатора JSON: невозможно десериализовать текущий массив JSON (например, [1,2,3]) в тип 'Submission # 0 + RuleMessage', потому что для этого типа требуется объект JSON (например, {"name": "value"}) для десериализовать правильно. Чтобы исправить эту ошибку, либо измените JSON на объект JSON (например, {"name": "value"}), либо измените десериализованный тип на массив или тип, реализующий интерфейс коллекции (например, ICollection, IList), например List, который может десериализоваться из массива JSON. JsonArrayAttribute также можно добавить к типу, чтобы заставить его десериализоваться из массива JSON.
Код функции:
using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Microsoft.Azure.NotificationHubs;
public static void Run(List<RuleMessage> inputEventMessage, string inputBlob, out Notification notification, out string outputBlob, TraceWriter log)
{
if (inputEventMessage == null || inputEventMessage.Count != 1)
{
log.Info($"The inputEventMessage array was null or didn't contain exactly one item.");
notification = null;
outputBlob = inputBlob;
return;
}
log.Info($"C# Event Hub trigger function processed a message: {inputEventMessage[0]}");
if (String.IsNullOrEmpty(inputBlob))
inputBlob = DateTime.MinValue.ToString();
DateTime lastEvent = DateTime.Parse(inputBlob);
TimeSpan duration = DateTime.Now - lastEvent;
if (duration.TotalMinutes >= 0) {
notification = GetGcmMessage(inputMessage.First());
log.Info($"Sending notification message: {notification.Body}");
outputBlob = DateTime.Now.ToString();
}
else {
log.Info($"Not sending notification message because of timer ({(int)duration.TotalMinutes} minutes ago).");
notification = null;
outputBlob = inputBlob;
}
}
private static Notification GetGcmMessage(RuleMessage input)
{
string message;
if (input.readingtype == "leakage")
message = String.Format("[FUNCTION GCM] Leakage detected! Sensor {0} has detected a possible leak.", input.reading);
else
message = String.Format("[FUNCTION GCM] Sensor {0} is reading {1:0.0}, threshold is {2:0.0}.", input.readingtype, input.reading, input.threshold);
message = "{\"data\":{\"message\":\""+message+"\"}}";
return new GcmNotification(message);
}
public class RuleMessage
{
public string deviceid;
public string readingtype;
public object reading;
public double threshold;
public DateTime time;
}
Обновление 28-6-2016: мне не удалось заставить его работать, переключив вывод ASA на строку, разделенную так, чтобы он больше не генерировал массив JSON. Это темп. исправить, потому что привязка функции теперь не работает, как только в выходных данных появляется более одной строки (что может случиться).
В любом случае, теперь я приступил к установке tagExpression, согласно инструкции, которую я изменил на:
{
"type": "notificationHub",
"name": "notification",
"hubName": "repsaj-neptune-notifications",
"connection": "repsaj-neptune-notifications_NOTIFICATIONHUB",
"direction": "out",
"tagExpression": "deviceId:{deviceid}"
}
Где {deviceid}
равно свойству deviceid в моем POCO RuleMessage. К сожалению, это не работает, когда я вызываю функцию, которую он выводит:
Исключение при выполнении функции: Functions.submerged-function-ruleout. Microsoft.Azure.WebJobs.Host: параметр привязки исключения «уведомление». Microsoft.Azure.WebJobs.Host: нет значения для именованного параметра deviceid.
Что неверно, я точно знаю, что свойство было установлено, поскольку я зарегистрировал его в окне вывода. Я также пробовал что-то вроде {inputEventMessage.deviceid}, но это тоже не работает (так как я не понимал, как среда выполнения отображает {deviceid} на правильный объект ввода, когда их больше одного.