反序列化从 node.js (azure sdk) 发送的 Azure ServiceBus 队列消息时出错

Posted

技术标签:

【中文标题】反序列化从 node.js (azure sdk) 发送的 Azure ServiceBus 队列消息时出错【英文标题】:Error while deserializing Azure ServiceBus Queue message sent from node.js (azure sdk) 【发布时间】:2015-04-22 14:36:23 【问题描述】:

这是我的场景:

我正在使用 node azure sdk 从 Node.js 发送一条 Azure ServiceBus Queue 消息,如下所示:

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

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

我有一个正在监听队列的 c# worker 角色:

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

Client.OnMessage((receivedMessage) =>

    var body = receivedMessage.GetBody<string>();
);

GetBody 方法被执行时,我得到以下错误:

反序列化 System.String 类型的对象时出错。输入源格式不正确

【问题讨论】:

【参考方案1】:

经过一番挖掘,我找到了THIS 帮助我找到解决方案的文章:

Client.OnMessage((receivedMessage) =>

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

如果有人遇到过这个问题并找到了更好的解决方案,请告诉我!

谢谢!

【讨论】:

【参考方案2】:

致任何发现此问题的人,如果他们在使用 Service Bus Explorer 发送消息时收到此错误(如我)。

确保在下拉列表中指定正确的消息类型:

【讨论】:

【参考方案3】:

感谢您的更新,我正在做相反的事情,这对我有帮助。我想我会添加到您的解决方案中以确保完整性。 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

【讨论】:

【参考方案4】:

使用 nuget 包:Microsoft.Azure.ServiceBus

以下信息作为评论包含在里面:

    如果仅使用此 Microsoft.Azure.ServiceBus 发送和接收消息 客户端库,则以下扩展方法不相关,不应使用。 如果此客户端库将用于接收使用 WindowsAzure.Messaging 客户端库和此 (Microsoft.Azure.ServiceBus) 库发送的消息,则用户需要添加用户属性 Microsoft.Azure.ServiceBus.Message发送消息时的 .UserProperties。收到消息后,可以检查此属性以确定消息是否来自 WindowsAzure.Messaging 客户端库,如果是,则使用 message.GetBody() 扩展方法获取与消息关联的实际正文。

---------------------------------------------- 场景到 使用 GetBody 扩展方法:-------------------------------------------- -- 如果消息是使用 WindowsAzure.Messaging 客户端库构建的 如下: var message1 = new BrokeredMessage("contoso"); // 发送一个纯字符串 var message2 = new BrokeredMessage(sampleObject); // 发送一个实际的客户对象 var message3 = new BrokeredMessage(Encoding.UTF8.GetBytes("contoso")); // 发送 一个 UTF8 编码的字节数组对象 await messageSender.SendAsync(message1);等待 messageSender.SendAsync(message2);等待 messageSender.SendAsync(message3); 然后使用此客户端库检索原始对象,如下所示:(通过 默认 Microsoft.Azure.ServiceBus.InteropExtensions.DataContractBinarySerializer 将用于反序列化和检索主体。如果序列化程序不是 使用的,显式传入序列化程序。) var message1 = 等待 messageReceiver.ReceiveAsync(); var returnedData1 = message1.GetBody(); var message2 = 等待 messageReceiver.ReceiveAsync(); var returnedData2 = message1.GetBody(); var message3 = 等待 messageReceiver.ReceiveAsync(); var returnedData3Bytes = message1.GetBody(); Console.WriteLine($"Message3 String: Encoding.UTF8.GetString(returnedData3Bytes)"); ------------------------------------------------- 场景不使用 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); // 因为消息是 作为 Stream 发送,此处不需要反序列化。

希望对你有帮助

【讨论】:

【参考方案5】:

使用最新的服务总线客户端库(.NET、JS、Java、Python),您可以使用 JS 库发送消息,如下所示:

const serviceBusClient = new ServiceBusClient("<connectionstring>");

const sender = serviceBusClient.createSender("<queuename>");
await sender.sendMessages([
  body: 
    title: "hello"
  
]);

请注意,.sendMessages 将列表作为输入,即使您只是发送一条消息。

并使用 .NET 库获取接收到的消息的正文,如下所示:

await using var client = new ServiceBusClient("<connectionstring>");
ServiceBusReceiver receiver = client.CreateReceiver("<queuename>");

ServiceBusReceivedMessage receivedMessage = await receiver.ReceiveMessageAsync();
string body = receivedMessage.Body.ToString();
Console.WriteLine(body); //prints "title":"hello"

【讨论】:

以上是关于反序列化从 node.js (azure sdk) 发送的 Azure ServiceBus 队列消息时出错的主要内容,如果未能解决你的问题,请参考以下文章

Azure 存储 Node.js SDK - MD5 哈希与本地不同

Node.js根本没有float:浮点反序列化错误背后的故事

C# - 如何从 Azure DevOps 工作项列表反序列化 json?

漏洞公告Node.js反序列化远程代码执行漏洞通告CVE-2017-5941

技术讨论 | 记一次Node.Js反序列化攻击测试

利用 Node.js 反序列化漏洞远程执行代码