无法确定Azure Service Bus GetBody <stream>编码

时间:2017-05-30 21:48:21

标签: c#-4.0 azureservicebus

我正在尝试从.NET客户端的AzureServiceBus获取BrokeredMessage,并根据进入的消息类型选择如何处理消息,但未设置ContentType和其他消息属性。

我的测试邮件发送如下:

            var client = 
QueueClient.CreateFromConnectionString(connectionString, queueName);
        var message = new BrokeredMessage("test");
            client.Send(message);

我要接收的代码是使用GetBody,以便我可以检查序列化数据并决定如何处理它:

var stream = message.GetBody<Stream>();
                       string s = null;
                       using (StreamReader sr = new StreamReader(stream))
                       {
                           s = sr.ReadToEnd();
                       }

问题是上面的“s”最终看起来应该是从DataContractSerializer创建的XML,但它编码奇怪。我在接收方尝试了很多编码,似乎没有一个能让我有效的xml。示例结果:

@string3http://schemas.microsoft.com/2003/10/Serialization/�test

我看到了序列化命名空间,看起来它应该以&lt; string开头,但是你可以看到我正在获取控制字符。有没有人知道如何尝试将序列化数据作为有效的XML获取,以便我可以动态处理它?

TIA提供任何帮助。

要非常清楚我想测试身体,所以我可以做类似的事情:

if(BodyIsString(s)){做某事} if(BodyIsPerson(s)){做别的事情}

如果我能两次得到这个,那真的很容易。

2 个答案:

答案 0 :(得分:1)

您将有效负载作为字符串传递

var message = new BrokeredMessage("test");

因此它被序列化为一个字符串。收到后,你应该按照以下方式将身体作为一个字符串:

var body = message.GetBody<string>();

如果您使用流实际构建代理消息,则可以使用Stream

答案 1 :(得分:1)

正如肖恩·费尔德曼提到的,当发送消息是字符串类型时,我们可以使用

var body = message.GetBody<string>();

获取邮件正文,在我反编译WindowsAzure.ServiceBus.dll然后获取代码:

 public T GetBody<T>()
    {
      if (typeof (T) == typeof (Stream))
      {
        this.SetGetBodyCalled();
        return (T) this.BodyStream;
      }
      if (!this.bodyObjectDecoded || this.bodyObject == null)
        return this.GetBody<T>((XmlObjectSerializer) new DataContractBinarySerializer(typeof (T)));
      this.SetGetBodyCalled();
      return (T) this.bodyObject;
    }

我发现如果发送消息 不是Stream类型,它将是DataContractBinarySerializer。所以我们也可以通过以下方式获取消息体

var stream = message.GetBody<Stream>();
var messageBody = new DataContractSerializer(typeof(string)).ReadObject(XmlDictionaryReader.CreateBinaryReader(stream, XmlDictionaryReaderQuotas.Max));

从反编译代码我们可以知道,如果我们发送流消息,我们可以按照您提到的方式获取消息体。

发送流消息代码:

var client = QueueClient.CreateFromConnectionString(connectionString, queueName);
var byteArray = Encoding.UTF8.GetBytes("test stream");
MemoryStream stream = new MemoryStream(byteArray);
client.Send(new BrokeredMessage(stream)); 

然后收到您提到的应该有效的消息:

var stream = message.GetBody<Stream>();
                       string s = null;
                       using (StreamReader sr = new StreamReader(stream))
                       {
                           s = sr.ReadToEnd();
                       }

修改:根据更新问题:

  

如果我能两次得到这个,那将非常容易。

我们可以克隆BrokerMessage

var newMessage = receiveMessage.Clone();

<强> EDIT2:

如果我们在发送过程中设置它,我们也可以获取消息属性以了解正文类型。以标签为例:

 var message = new BrokeredMessage(object);
 message.Label = "Type of message body";
 client.Send(message);

当我们收到消息时,我们可以收到消息标签值,然后选择相应的方式来获取正文。