Ошибка при десериализации сообщения Azure ServiceBus Queue, отправленного из node.js(azure sdk)

Здесь мой сценарий:

Я отправляю сообщение очереди Azure ServiceBus из Node.js с помощью node azure sdk, например:

var message = {
    body: JSON.stringify({ foo: 'Bar' })
};

serviceBusService.sendQueueMessage('myQueue', message, function (error) {
    if (!error) {
        console.log('msessage sent');
    }
});

У меня есть рабочая роль С#, которая слушает очередь:

QueueClient Client = QueueClient.CreateFromConnectionString(connStr, QueueName);

Client.OnMessage((receivedMessage) =>
{
    var body = receivedMessage.GetBody<string>();
});

Когда метод GetBody выполняется, я получаю следующую ошибку:

Ошибка десериализации объекта типа System.String. Источник ввода не правильно отформатирован.

Ответ 1

После некоторого копания я нашел ЭТУ статью, которая помогла мне получить решение:


Client.OnMessage((receivedMessage) =>
{
    var bodyJson = new StreamReader(receivedMessage.GetBody<Stream>(), Encoding.UTF8).ReadToEnd();
    var myMessage = JsonConvert.DeserializeObject<MyMessage>(bodyJson);
});


Если кто-то столкнулся с этой проблемой и нашел лучшее решение, пожалуйста, дайте мне знать!

Спасибо!

Ответ 2

Спасибо за обновление, я делал обратное, и это помогло мне. Я думал, что добавлю к вашему решению полноту. Метод DeserializeObject требует определения класса MyMessage. В вашем исходном посте ваш JSON:

{ foo: 'Bar' }

Если мы отбросим это в json2csharp (json2csharp.com), теперь у нас есть класс, необходимый для завершения вашего решения:

public class MyMessage
{
  public string foo { get; set; }
}

Конечно, у зависимостей есть Newtonsoft.Json пакет, добавленный в ваше решение Visual Studio:

Install-Package Newtonsoft.Json -Pre

Ответ 3

Использование пакета nuget: Microsoft.Azure.ServiceBus

Следующая информация содержится внутри как комментарий:

  1. Если сообщение только отправляется и принимается с использованием этого Microsoft.Azure.ServiceBus клиентская библиотека, то нижеприведенные методы расширения не актуальны и не должны использоваться.
  2. Если эта клиентская библиотека будет использоваться для получения сообщений, отправленных с использованием как клиентской библиотеки WindowsAzure.Messaging, так и этой библиотеки (Microsoft.Azure.ServiceBus), то пользователям необходимо добавить свойство User Microsoft.Azure.ServiceBus.Message.UserProperties, в то время как отправив сообщение. Получив сообщение, можно проверить это свойство, чтобы определить, было ли сообщение из клиентской библиотеки WindowsAzure.Messaging и, если да, использовать метод расширения message.GetBody(), чтобы получить фактическое тело, связанное с сообщением.

---------------------------------------------- Сценарии     используйте метод GetBody Extension: -------------------------------------------- -     Если сообщение было создано с использованием клиентской библиотеки WindowsAzure.Messaging как     следующим образом:     var message1 = new BrokeredMessage ("contoso");//Отправка простой строки var     message2 = новый BrokeredMessage (sampleObject);//Отправка объекта реального клиента     var message3 = new BrokeredMessage (Encoding.UTF8.GetBytes("contoso"));//Отправка     объект байтового массива в кодировке UTF8 ожидает messageSender.SendAsync(message1); Ждите     messageSender.SendAsync(message2); ожидание messageSender.SendAsync(message3);     Затем получите исходные объекты, используя эту клиентскую библиотеку, следующим образом:     по умолчанию Microsoft.Azure.ServiceBus.InteropExtensions.DataContractBinarySerializer     будет использоваться для десериализации и извлечения тела. Если сериализатор кроме     что было использовано, передайте в сериализаторе явно.)     var message1 = await messageReceiver.ReceiveAsync(); var returnData1 = message1.GetBody();     var message2 = await messageReceiver.ReceiveAsync(); var returnData2 = message1.GetBody();     var message3 = await messageReceiver.ReceiveAsync(); var returnData3Bytes =     message1.GetBody(); Console.WriteLine($ "Message3 String: {Encoding.UTF8.GetString(returnData3Bytes)}");     ------------------------------------------------- Сценарии НЕ использовать GetBody     Метод расширения: ----------------------------------------------- - Если сообщение     был отправлен с помощью клиентской библиотеки WindowsAzure.Messaging следующим образом: var message4     = new BrokeredMessage (new MemoryStream (Encoding.UTF8.GetBytes("contoso"))); Ждите     messageSender.SendAsync(message4); Затем получить исходные объекты, используя эту     клиентская библиотека выглядит следующим образом: var message4 = await messageReceiver.ReceiveAsync();     возвращаемая строка = Encoding.UTF8.GetString(message4.Body);//Так как сообщение было     отправлено как поток, здесь не требуется десериализация.

Да поможет тебе