Azure ServiceBus消息序列化/反序列化

28

我正在使用.NET Core应用程序将一个对象通过Azure Service Bus Queue发送并由Web Job(.NET Core)接收。

我的问题是如何序列化/反序列化以发送/接收对象?

我发现很多关于传统BroakerMessage.GetBody()的引用来接收消息,但是没有对新的.NET Core方法。请建议,谢谢。

发送者代码:

using Microsoft.Azure.ServiceBus;

MyClass object = new MyClass();
var message = new Message(object);
await queueClient.SendAsync(message);

接收者代码:

using Microsoft.Azure.ServiceBus;

public void ProcessQueueMessage([ServiceBusTrigger("queue")] Message message, TextWriter log)
{
}
3个回答

44

可以使用JSON序列化来传输这些对象/实体。

假设以下类是将要发送到/接收自Azure服务总线队列的对象实例的类型:

public class Customer{ public string Name { get; set; } public string Email { get; set; } }

---发送---

以下是一个示例代码(.NET Core 2.0控制台应用程序),用于发送客户对象实例:

QueueClient queueClient = new QueueClient(connectionString, queueName);
string messageBody = JsonConvert.SerializeObject(obj);
Message message = new Message(Encoding.UTF8.GetBytes(messageBody))
{
    SessionId = sessionId
};
await queueClient.SendAsync(message);

--- 收到 ---

以下是一个Azure函数(Service Bus队列触发器/ .NET Standard 2.0)的示例代码,用于接收消息并将其反序列化:

[FunctionName("ServiceBusQueueFunction")]
public static void Run([ServiceBusTrigger("taskqueue", Connection = "ServiceBusConnectionString")] Message message, TraceWriter log)
{
    Customer customer = JsonConvert.DeserializeObject<Customer>(Encoding.UTF8.GetString(message.Body));
}

以下NuGet包用于上述示例的使用/测试:

  • Microsoft.Azure.ServiceBus(版本3.0.2)。
  • Newtonsoft.Json(版本11.0.2)。

建议阅读:以下是有关JSON.NET性能提示的文章链接:https://www.newtonsoft.com/json/help/html/Performance.htm


设计理念: 在最新的Microsoft.Azure.ServiceBus中,内置的POCO序列化支持已被删除。原因是“虽然这种隐藏的序列化技术很方便,但应用程序应该对对象序列化进行明确控制,并将它们的对象图转换为流,然后在包含它们到消息中之前,做出相反的操作以获得互操作性结果。”

https://learn.microsoft.com/en-us/azure/service-bus-messaging/service-bus-messages-payloads


非常感谢,你是救命恩人,我为此卡了几个小时。 - Username Not Exist
1
你真的测试过这个吗?反序列化对我来说不起作用,因为我的 message.Body 有一堆不是 JSON 的垃圾。这是我的消息创建代码:var queueBody = new QueueBody { Name = $"JSmith{i}" };string messageBody = JsonConvert.SerializeObject(queueBody); var message = new Message { Body = Encoding.UTF8.GetBytes(messageBody), ContentType = "application/json" }; - g.t.w.d
但是如果接收者不知道消息是一个“Customer”,那么在哪里可以检索到消息类型以便动态决定要反序列化成哪种类型? - diegosasw
我也遇到了同样的问题。在接收文本开头处,我得到了@ \ fbase64Binary \ b3http://schemas.microsoft.com/2003/10/Serialization/ \ u0002 \ u0001 {,并且在此行上失败:JsonConvert.DeserializeObject <MyObject>(body); 出现错误“解析值时遇到意外字符:@”。 - johnstaveley

3
如何序列化/反序列化以发送/接收对象? 请参考以下演示代码:
发送消息:
var body = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(obj));
await  queueClient.SendAsync(new Message { Body = body, ContentType = "text/plain" });

在 .net core 的 WebJob 中。
var body = Encoding.UTF8.GetString(message.Body);
var obj = JsonConvert.DeserializeObject<T>(body);

测试结果:

测试结果:

enter image description here


有没有办法在反序列化之前知道消息类型? - diegosasw

3
由于以下原因,这两者对我都不起作用:
由于我们接收到的消息主体是**文本格式**,尝试将其解析为JSON时出现了异常。
"@\u0006string\b3http://schemas.microsoft.com/2003/10/Serialization/?\u000b{ \"a\": \"1\"}"

这是因为“Brokered Message使用DataContractSerializer和二进制XmlDictionaryWriter从给定对象实例化一个新的BrokeredMessage类”的原因。
参考:https://www.bfcamara.com/post/84113031238/send-a-message-to-an-azure-service-bus-queue-with 所以我使用了这篇博客文章:https://abhishekrlal.com/2012/03/30/formatting-the-content-for-service-bus-messages/ 示例1:使用字符串
当使用字符串和默认的(DataContract + Binary)序列化程序创建BrokeredMessage时:
BrokeredMessage stringDefaultMessage = new BrokeredMessage("default string");

您可以将此消息接收为:

string s = receiveMessage.GetBody<string>();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接