我正在尝试从.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)){做别的事情}
如果我能两次得到这个,那真的很容易。
答案 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);
当我们收到消息时,我们可以收到消息标签值,然后选择相应的方式来获取正文。