You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Microsoft.Azure.ServiceBus 2.0.0接收队列消息出现编码异常

解决Azure ServiceBus新旧版本消息解码乱码问题

嘿,这个问题我之前也踩过坑!核心原因是新旧ServiceBus SDK对消息Body的处理逻辑完全不一样,导致你直接用UTF8转字符串得到了乱码。

问题根源拆解

你用的旧版WindowsAzure.ServiceBus 4.1.6里的BrokeredMessage(旧版的消息类是这个),默认会把你传入的对象用BinaryFormatter序列化后放到Body里——哪怕你想传的是XML文本,只要直接把包含XML的对象丢给它,它就会自动序列化整个对象,而不是直接存XML的字节。

而新版Microsoft.Azure.ServiceBus 2.0.0的ServiceBusMessage拿到的Body是原始的序列化字节,这些字节根本不是纯UTF8的XML,而是BinaryFormatter序列化后的二进制数据,所以直接转字符串肯定会出现意外字符。

两种解决方案,看你需求选

方案1:接收端适配旧版的序列化逻辑

如果发送端代码暂时没法改,那接收端需要用BinaryFormatter反序列化Body字节,还原出原来的对象,再提取XML内容:

// 接收端代码(Microsoft.Azure.ServiceBus 2.0.0)
using (var memoryStream = new MemoryStream(serviceBusMessage.Body))
{
    var formatter = new BinaryFormatter();
    // 注意:接收端必须有发送端那个Message类的完整定义,包括序列化特性
    var originalMsg = (Message)formatter.Deserialize(memoryStream);
    // 假设originalMsg里有你要的XML内容,比如叫XmlContent属性
    string validXml = originalMsg.XmlContent;
    // 现在就可以正常处理XML了
}

⚠️ 小提示:如果发送端的Message类结构有变更,或者接收端的类定义和发送端不一致,BinaryFormatter会反序列化失败,这种方式适合发送端代码暂时不能动的场景。

方案2:修改发送端,直接发送纯XML字节

如果能改发送端代码,这是更稳妥的方式——直接把XML转成UTF8字节传给BrokeredMessage,避免自动序列化:

// 旧版WindowsAzure.ServiceBus 4.1.6发送端修改后的代码
private void SendToProcessingQueue(Guid accountId, Message msg)
{
    string queueName = msg.MessageType.ToLower();
    var client = CreateQueueClient(queueName);
    
    // 把XML内容直接转成UTF8字节
    byte[] xmlBytes = Encoding.UTF8.GetBytes(msg.YourXmlProperty);
    // 用MemoryStream包装,第二个参数false表示不接管流,避免自动序列化
    var brokeredMsg = new BrokeredMessage(new MemoryStream(xmlBytes), false);
    
    client.Send(brokeredMsg);
}

这样修改后,接收端直接用Encoding.UTF8.GetString(serviceBusMessage.Body)就能拿到正常的XML了,完全不用额外处理。

额外情况处理

如果发送端之前是用BrokeredMessage的字符串构造函数(比如new BrokeredMessage(xmlString)),那它默认用的是DataContractSerializer序列化字符串,这时候接收端需要用DataContractSerializer来反序列化,而不是BinaryFormatter:

using (var stream = new MemoryStream(serviceBusMessage.Body))
{
    var serializer = new DataContractSerializer(typeof(string));
    string xmlContent = (string)serializer.ReadObject(stream);
}

总之,核心就是对齐发送端和接收端的序列化/反序列化方式,新旧SDK的消息处理逻辑差异很大,一定要注意这点!

内容的提问来源于stack exchange,提问作者Eivind Gussiås Løkseth

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 06:58:56