Десериализация контента ServiceBus в приложении логики Azure - PullRequest
0 голосов
/ 08 мая 2018

Я пытаюсь прочитать текст сообщения в приложении логики Azure, но у меня не так много успеха. Я видел много предложений, которые говорят, что тело кодируется в base64, и предлагают использовать для декодирования следующее:

@{json(base64ToString(triggerBody()?['ContentData']))}

Часть base64ToString(...) правильно декодирует содержимое в строку, но, похоже, строка содержит префикс с дополнительной информацией о сериализации в начале:

@string3http://schemas.microsoft.com/2003/10/Serialization/�3{"Foo":"Bar"}

В этой строке также есть несколько дополнительных символов, которые не отображаются в моем браузере. Таким образом, функция json(...) не принимает ввод и выдает ошибку.

InvalidTemplate. Невозможно обработать выражения языка шаблона в действие «HTTP» вводит в строке «1» и столбце «2451»: «Шаблон Параметр функции языка 'json' недопустим. Предоставленное значение @string3http://schemas.microsoft.com/2003/10/Serialization/�3{"Foo":"bar" } не может быть проанализирован: Unexpected character encountered while parsing value: @. Path '', line 0, position 0.. Пожалуйста, смотрите https://aka.ms/logicexpressions#json для подробностей использования. '.

Для справки, сообщения добавляются в тему с помощью клиента служебной шины .NET (клиент не должен иметь значения, но это выглядит скорее на C # -ish):

await TopicClient.SendAsync(new BrokeredMessage(JsonConvert.SerializeObject(item)));

Как я могу правильно прочитать это как объект JSON в моем приложении логики?

Ответы [ 3 ]

0 голосов
/ 08 мая 2018

Это - , вызванное тем, как сообщение помещается в ServiceBus, в частности в код C #. Я использовал следующий код для добавления нового сообщения:

var json = JsonConvert.SerializeObject(item);
var message = new BrokeredMessage(json);
await TopicClient.SendAsync(message);

Этот код выглядит нормально и работает между различными службами C # без проблем. Проблема вызвана тем, что конструктор BrokeredMessage(Object) сериализует передаваемую ему полезную нагрузку:

Инициализирует новый экземпляр класса BrokeredMessage из заданного объекта с помощью DataContractSerializer с двоичным XmlDictionaryWriter.

Это означает, что содержимое сериализуется в виде двоичного XML, что объясняет префикс и нераспознаваемые символы. Это скрыто реализацией C # при десериализации и возвращает ожидаемый объект, но становится очевидным при использовании другой библиотеки (например, библиотеки Azure Logic Apps).

Есть две альтернативы для решения этой проблемы:

  • Убедитесь, что получатель может обрабатывать сообщения в двоичном формате XML
  • Убедитесь, что отправитель действительно использует нужный нам формат, например, JSON.

Ответ Пако де ла Круса обрабатывает первый случай, используя substring, indexOf и lastIndexOf:

@json(substring(base64ToString(triggerBody()?['ContentData']), indexof(base64ToString(triggerBody()?['ContentData']), '{'), add(1, sub(lastindexof(base64ToString(triggerBody()?['ContentData']), '}'), indexof(base64ToString(triggerBody()?['ContentData']), '}')))))

Что касается второго случая, то устранение проблемы в источнике просто предполагает использование конструктора BrokeredMessage(Stream). Таким образом, мы имеем прямой контроль над контентом:

var json = JsonConvert.SerializeObject(item);
var bytes = Encoding.UTF8.GetBytes(json);
var stream = new MemoryStream(bytes);
var message = new BrokeredMessage(stream, true);
await TopicClient.SendAsync(message);
0 голосов
/ 13 декабря 2018

Решение Пако-де-ла-Крус сработало для меня, хотя мне пришлось поменять последний '}' в выражении на '{', в противном случае он находит неправильный конец сегмента данных.

Я также разделил его на два этапа, чтобы сделать его немного более управляемым.

Сначала я получаю декодированную строку из сообщения в переменную (которую я назвал MC), используя:

@{base64ToString(triggerBody()?['ContentData'])}

затем в другом действии приложения логики выполните извлечение подстроки:

@{substring(variables('MC'),indexof(variables('MC'),'{'),add(1,sub(lastindexof(variables('MC'),'}'),indexof(variables('MC'),'{'))))}

Обратите внимание, что последний строковый литерал '{' инвертирован из решения Пако. ​​

Это работает для моих тестовых случаев, но я не уверен, насколько это надежно.

Кроме того, я оставил это как String, я делаю преобразование в JSON позже в моем приложении логики.

0 голосов
/ 08 мая 2018

Вы можете использовать функцию substring вместе с indexOf и lastIndexOf, чтобы получить только подстроку JSON.

К сожалению, это довольно сложно, но должно выглядеть примерно так:

@json(substring(base64ToString(triggerBody()?['ContentData']), indexof(base64ToString(triggerBody()?['ContentData']), '{'), add(1, sub(lastindexof(base64ToString(triggerBody()?['ContentData']), '}'), indexof(base64ToString(triggerBody()?['ContentData']), '}')))))

Подробнее о том, как использовать эти функции здесь .

HTH

...