Azure Logic Apps发送Service Bus消息:能否以字符串而非流发送?
核心结论
很遗憾,目前Logic Apps的"Send Message"动作向Service Bus主题发送消息时,确实默认是以Stream的形式传递内容,没办法直接配置成原生字符串类型。你之前尝试修改Content-Type为application/json、System.String或text/plain都无效,是因为这个动作的底层实现逻辑决定了消息体的传输格式,不是单纯靠HTTP头就能改变的。
为什么会触发序列化异常?
你用message.GetBody<string>()报错的根源在于:Logic Apps发送消息时,并没有按照DataContractSerializer期望的XML序列化格式来包装字符串,而是直接把原始内容以流的形式写入消息体。而GetBody<T>()默认会调用DataContractBinarySerializer去反序列化,这就导致了XML格式不匹配的异常——它试图把纯文本/JSON当成XML来解析,自然会抛出"The input source is not correctly formatted"的错误。
可行的替代解决方案
虽然不能直接让Logic Apps发送原生字符串,但有两种方式能让你的控制台应用顺利以字符串方式读取消息:
方案1:在Logic Apps中预先包装字符串格式
在Logic Apps的"Send Message"动作里,把要发送的内容用XML包装成符合DataContractSerializer要求的格式。比如你的原始消息是{"name":"test"},需要包装成:
<string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">{"name":"test"}</string>
这样修改后,你原来的message.GetBody<string>()代码就能正常反序列化,不需要改动控制台应用的逻辑。
方案2:在控制台应用中适配流的读取逻辑
如果你不想修改Logic Apps的配置,除了你已经实现的读取流并转换为字符串的代码,还可以用更简洁的方式,直接指定DataContractSerializer来处理流内容:
SubscriptionClient subClient = SubscriptionClient.CreateFromConnectionString(connstr, topicName, subscriptionName); OnMessageOptions options = new OnMessageOptions(); options.AutoComplete = true; options.MaxConcurrentCalls = 1; subClient.OnMessage((message) => { try { var serializer = new DataContractSerializer(typeof(string)); string messageJson = (string)serializer.ReadObject(message.GetBody<Stream>()); Console.WriteLine(messageJson); } catch (Exception ex) { Console.WriteLine(ex.ToString()); } }, options);
补充说明
这个行为其实不算Logic Apps的"限制",而是它的通用设计——为了兼容二进制数据、大文件等多种内容类型,采用流的形式传输消息体是更灵活的选择。如果你的场景确实需要严格的字符串序列化,上述两种方案都能很好地解决问题。
内容的提问来源于stack exchange,提问作者Pranshu Gupta

