如何用Azure.Messaging.ServiceBus反序列化Microsoft.ServiceBus.Messaging发送的消息?
解决旧版Service Bus消息的反序列化问题
旧版Microsoft.ServiceBus.Messaging(NuGet包ServiceBus.v1_1)发送消息时,默认使用DataContractJsonSerializer序列化,消息体开头会附加类型标识前缀(比如你看到的@\u000eCommandMessage\bU),这不是标准JSON格式,直接用JsonConvert.DeserializeObject解析肯定会抛出格式异常。
以下是两种可行的解决方法:
方法一:手动剥离前缀后用JsonConvert解析
先从消息体中提取出纯JSON部分,再用Newtonsoft.Json反序列化:
[FunctionName("FunctionHandler")] public async Task RunFunction( [ServiceBusTrigger("%ServiceBusQueueName%", Connection = ApFunctionDefaults.ServiceBusNames.ServiceBusConnectionString)] ServiceBusReceivedMessage queueMessage) { var bodyBytes = queueMessage.Body.ToArray(); var bodyString = Encoding.UTF8.GetString(bodyBytes); // 定位纯JSON的起始位置:找到第一个'{'的索引 int jsonStartIndex = bodyString.IndexOf('{'); if (jsonStartIndex == -1) { throw new InvalidOperationException("无法找到消息中的JSON内容"); } var pureJson = bodyString.Substring(jsonStartIndex); var jsonSettings = KnownTypesBinder.GetSerializerSettings(KnownTypeProvider.GetKnownTypes()); var command = JsonConvert.DeserializeObject<MyDto>(pureJson, jsonSettings); // 后续业务逻辑 }
方法二:直接使用DataContractJsonSerializer解析
既然旧版用的是DataContractJsonSerializer,新版接收时也用它来反序列化,能自动识别前缀:
注意:需要先引用NuGet包System.Runtime.Serialization
using System.Runtime.Serialization.Json; [FunctionName("FunctionHandler")] public async Task RunFunction( [ServiceBusTrigger("%ServiceBusQueueName%", Connection = ApFunctionDefaults.ServiceBusNames.ServiceBusConnectionString)] ServiceBusReceivedMessage queueMessage) { var bodyStream = new MemoryStream(queueMessage.Body.ToArray()); var serializer = new DataContractJsonSerializer(typeof(MyDto)); var command = (MyDto)serializer.ReadObject(bodyStream); // 后续业务逻辑 }
如果你的MyDto带有[DataContract]和[DataMember]特性,这种方法会更适配旧版的序列化逻辑,避免手动处理前缀的潜在问题。
内容的提问来源于stack exchange,提问作者Simon
相关产品推荐
相关产品推荐

