为什么 Azure WebJob ServiceBus 默认反序列化 XML?

Mic*_*ltu 5 azureservicebus azure-webjobs azure-webjobssdk

我有一个简单的 Azure WebJobs ServiceBusTrigger,看起来像

public static async void ProcessQueueMessage([ServiceBusTrigger("myqueuename")] String json, TextWriter log) { ... }
Run Code Online (Sandbox Code Playgroud)

不幸的是,它无法将 JSON 反序列化为 XML(不足为奇)。我检查了有效负载并确认它只是一个 UTF-8 编码的字节数组。我有两个问题。

  1. 为什么假设我的 String 是 XML?
  2. 我怎么告诉它不,没有 XML,只有一个字符串?

堆栈跟踪:

System.InvalidOperationException: Exception binding parameter 'json' ---> System.Runtime.Serialization.SerializationException: There was an error deserializing the object of type System.String. The input source is not correctly formatted. ---> System.Xml.XmlException: The input source is not correctly formatted.
 at System.Xml.XmlExceptionHelper.ThrowXmlException(XmlDictionaryReader reader, String res, String arg1, String arg2, String arg3)
 at System.Xml.XmlBufferReader.ReadValue(XmlBinaryNodeType nodeType, ValueHandle value)
 at System.Xml.XmlBinaryReader.ReadNode()
 at System.Xml.XmlBinaryReader.Read()
 at System.Xml.XmlBaseReader.IsStartElement()
 at System.Xml.XmlBaseReader.IsStartElement(XmlDictionaryString localName, XmlDictionaryString namespaceUri)
 at System.Runtime.Serialization.XmlReaderDelegator.IsStartElement(XmlDictionaryString localname, XmlDictionaryString ns)
 at System.Runtime.Serialization.XmlObjectSerializer.IsRootElement(XmlReaderDelegator reader, DataContract contract, XmlDictionaryString name, XmlDictionaryString ns)
 at System.Runtime.Serialization.DataContractSerializer.InternalIsStartObject(XmlReaderDelegator reader)
 at System.Runtime.Serialization.DataContractSerializer.InternalReadObject(XmlReaderDelegator xmlReader, Boolean verifyObjectName, DataContractResolver dataContractResolver)
 at System.Runtime.Serialization.XmlObjectSerializer.ReadObjectHandleExceptions(XmlReaderDelegator reader, Boolean verifyObjectName, DataContractResolver dataContractResolver)
 --- End of inner exception stack trace ---
 at System.Runtime.Serialization.XmlObjectSerializer.ReadObjectHandleExceptions(XmlReaderDelegator reader, Boolean verifyObjectName, DataContractResolver dataContractResolver)
 at System.Runtime.Serialization.DataContractSerializer.ReadObject(XmlDictionaryReader reader, Boolean verifyObjectName)
 at Microsoft.ServiceBus.Messaging.DataContractBinarySerializer.ReadObject(XmlDictionaryReader reader, Boolean verifyObjectName)
 at System.Runtime.Serialization.XmlObjectSerializer.ReadObject(XmlReader reader, Boolean verifyObjectName)
 at System.Runtime.Serialization.XmlObjectSerializer.InternalReadObject(XmlReaderDelegator reader, Boolean verifyObjectName)
 at System.Runtime.Serialization.XmlObjectSerializer.InternalReadObject(XmlReaderDelegator reader, Boolean verifyObjectName, DataContractResolver dataContractResolver)
 at System.Runtime.Serialization.XmlObjectSerializer.ReadObjectHandleExceptions(XmlReaderDelegator reader, Boolean verifyObjectName, DataContractResolver dataContractResolver)
 at System.Runtime.Serialization.XmlObjectSerializer.ReadObject(XmlDictionaryReader reader)
 at Microsoft.ServiceBus.Messaging.DataContractBinarySerializer.ReadObject(Stream stream)
 at Microsoft.ServiceBus.Messaging.BrokeredMessage.GetBody[T](XmlObjectSerializer serializer)
 at Microsoft.ServiceBus.Messaging.BrokeredMessage.GetBody[T]()
 at Microsoft.Azure.WebJobs.ServiceBus.Triggers.BrokeredMessageToStringConverter.ConvertAsync(BrokeredMessage input, CancellationToken cancellationToken)
 at Microsoft.Azure.WebJobs.ServiceBus.Triggers.ConverterArgumentBindingProvider`1.ConverterArgumentBinding.<BindAsync>d__0.MoveNext()
Run Code Online (Sandbox Code Playgroud)

编辑:WebJobs 文档建议不仅应该我所做的工作 ( String),而且 ServiceBusTrigger 应该自动反序列化 JSON 对象。但是,如果我尝试取出 POCO,我仍然会收到 XML 反序列化错误。有趣的是,如果我将类型设置为 Byte[],我也会收到 XML 反序列化错误,这也应该可以工作。

编辑2:Stream也不起作用。似乎只有BrokeredMessage 适用于触发器,而 GetBody 是我能找到的从 BrokeredMessage 中获取字符串的唯一方法。

Vic*_*aci 2

如果您的有效负载是字符串,您有两个选择:

  1. 将参数类型改为BrokeredMessage然后自己反序列化
  2. BrokeredMessage.ContentType属性设置为text/plain(这假设您可以控制生成消息的代码)

除了String需要内容类型的奇怪情况外,规则是服务总线有效负载只能反序列化到与有效负载相同的对象。这是因为 ServiceBus 二进制序列化程序。