Microsoft 服务总线 REST 客户端 - 从 Queue 读取时出现问题
Microsoft Service Bus REST Client - Issues with reading from Queue
我们正在使用 Microsoft ServiceBus QueueClient 向服务总线发送消息。在接收消息时,我们正在使用 ServiceBus REST API。 body 的反序列化失败,我们无法找出根本原因。
发送消息的示例代码如下:
MessagingFactory messagingFactory =
MessagingFactory.CreateFromConnectionString(....);
Console.WriteLine("Creating Service Bus Queue Client...");
QueueClient queueSendClient = messagingFactory.CreateQueueClient(.);
// Send message M1 to the topic.
Console.WriteLine("Sending message.. ");
BrokeredMessage bm = CreateMessage();
queueSendClient.Send(bm);
CreateMessage 实例化一个具有序列化 object 实例的 BrokeredMessage。
private static BrokeredMessage CreateMessage()
{
JObject o1 = JObject.Parse(File.ReadAllText(@"..\..\requestJson.json"));
string jsonMessage = JsonConvert.SerializeObject(o1);
CommandMessage commandMessage = new CommandMessage();
JsonCommand content = new JsonCommand("abc", "def", jsonMessage);
List<Command> list = new List<Command>();
list.Add(content);
commandMessage.Initialize(list, false, false);
var message = new BrokeredMessage(commandMessage);
return message;
}
注意:CommandMessage、JsonCommand、Command 都装饰有[DataContract]。
如果我们也使用QueueClient 进行接收,那么消息的接收工作正常。但在我们的例子中,我们使用的是服务总线 Rest 客户端。
接收消息代码如下:
const string ServiceBusNamespace = "mysb2015-ns";
string baseAddressHttp = "https://" + ServiceBusNamespace + ".servicebus.windows.net/";
string queueAddress = baseAddressHttp + QueueName;
HttpResponseMessage response = await this.httpClient.PostAsync(address + "/messages/head?timeout=60", new ByteArrayContent(new Byte[0]));
byte[] body = response.Content.ReadAsByteArrayAsync().Result;
DataContractSerializer deserializer = new DataContractSerializer(typeof(CommandMessage));
using (MemoryStream ms = new MemoryStream(body))
{
CommandMessage cmdMsg = (CommandMessage)deserializer.ReadObject(ms);
}
读取 object 失败,但根级别的数据无效:
System.Runtime.Serialization.SerializationException 未处理
HResult=-2146233076
Message=反序列化 CommandMessage 类型的 object 时出错。根级别的数据无效。第 1 行,位置 1。
来源=System.Runtime.Serialization
我们查看了响应中的 content-type header 是 application/xml;utf-8.
Initializes a new instance of the BrokeredMessage class from a given
object by using DataContractSerializer with a binary
XmlDictionaryWriter.
当您将 BrokeredMessage 发送到队列时,XmlDictionaryWriter 正在添加其类型指示。如果使用QueueClient接收,就没有问题。因为它可以解决这个类型指示。但是,如果您使用的不是 QueueClient,您将遇到反序列化问题。
解决方案:
- Remove indicator before deserialize.
- Use other constructor of BrokeredMessage.
BrokeredMessage(Stream messageBodyStream, bool ownsStream)
and control the message body
yourself.
在这个 article 中,他们解释了问题和解决方案。
我们正在使用 Microsoft ServiceBus QueueClient 向服务总线发送消息。在接收消息时,我们正在使用 ServiceBus REST API。 body 的反序列化失败,我们无法找出根本原因。
发送消息的示例代码如下:
MessagingFactory messagingFactory =
MessagingFactory.CreateFromConnectionString(....);
Console.WriteLine("Creating Service Bus Queue Client...");
QueueClient queueSendClient = messagingFactory.CreateQueueClient(.);
// Send message M1 to the topic.
Console.WriteLine("Sending message.. ");
BrokeredMessage bm = CreateMessage();
queueSendClient.Send(bm);
CreateMessage 实例化一个具有序列化 object 实例的 BrokeredMessage。
private static BrokeredMessage CreateMessage()
{
JObject o1 = JObject.Parse(File.ReadAllText(@"..\..\requestJson.json"));
string jsonMessage = JsonConvert.SerializeObject(o1);
CommandMessage commandMessage = new CommandMessage();
JsonCommand content = new JsonCommand("abc", "def", jsonMessage);
List<Command> list = new List<Command>();
list.Add(content);
commandMessage.Initialize(list, false, false);
var message = new BrokeredMessage(commandMessage);
return message;
}
注意:CommandMessage、JsonCommand、Command 都装饰有[DataContract]。
如果我们也使用QueueClient 进行接收,那么消息的接收工作正常。但在我们的例子中,我们使用的是服务总线 Rest 客户端。
接收消息代码如下:
const string ServiceBusNamespace = "mysb2015-ns";
string baseAddressHttp = "https://" + ServiceBusNamespace + ".servicebus.windows.net/";
string queueAddress = baseAddressHttp + QueueName;
HttpResponseMessage response = await this.httpClient.PostAsync(address + "/messages/head?timeout=60", new ByteArrayContent(new Byte[0]));
byte[] body = response.Content.ReadAsByteArrayAsync().Result;
DataContractSerializer deserializer = new DataContractSerializer(typeof(CommandMessage));
using (MemoryStream ms = new MemoryStream(body))
{
CommandMessage cmdMsg = (CommandMessage)deserializer.ReadObject(ms);
}
读取 object 失败,但根级别的数据无效:
System.Runtime.Serialization.SerializationException 未处理 HResult=-2146233076 Message=反序列化 CommandMessage 类型的 object 时出错。根级别的数据无效。第 1 行,位置 1。 来源=System.Runtime.Serialization
我们查看了响应中的 content-type header 是 application/xml;utf-8.
Initializes a new instance of the BrokeredMessage class from a given object by using DataContractSerializer with a binary XmlDictionaryWriter.
当您将 BrokeredMessage 发送到队列时,XmlDictionaryWriter 正在添加其类型指示。如果使用QueueClient接收,就没有问题。因为它可以解决这个类型指示。但是,如果您使用的不是 QueueClient,您将遇到反序列化问题。
解决方案:
- Remove indicator before deserialize.
- Use other constructor of BrokeredMessage.
BrokeredMessage(Stream messageBodyStream, bool ownsStream)
and control the message body yourself.
在这个 article 中,他们解释了问题和解决方案。