C# 使用 azure brokeredmessage 在不知道类型的情况下获取正文

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15441853/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 16:50:32  来源:igfitidea点击:

with azure brokeredmessage get the body without knowing the type

c#azureazureservicebus

提问by yamspog

When you are using the brokered message in the Azure Service Bus, you can retrieve the body of the message with the call .GetBody. The code is simple:

在 Azure 服务总线中使用中转消息时,可以通过调用 .GetBody 检索消息正文。代码很简单:

var msg = subscription.Receive();
MyPayload payload = msg.GetBody<MyPayload>();

However, is there a way to retrieve the Body without explicitly knowing the class of the body object?

但是,有没有一种方法可以在不明确知道 body 对象的类的情况下检索 Body?

var msg = subscription.Receive();
Type bodyType = Type.GetType( msg.ContentType);

var payload = msg.GetBody<bodyType>();

采纳答案by yamspog

Here is the complete code to deserialize from the brokeredmessage:

这是从代理消息反序列化的完整代码:

public T GetBody<T>(BrokeredMessage brokeredMessage)
{
  var ct = brokeredMessage.ContentType;
  Type bodyType = Type.GetType(ct, true);

  var stream = brokeredMessage.GetBody<Stream>();
  DataContractSerializer serializer = new DataContractSerializer(bodyType);
  XmlDictionaryReader reader = XmlDictionaryReader.CreateBinaryReader(stream, XmlDictionaryReaderQuotas.Max);
  object deserializedBody = serializer.ReadObject(reader);
  T msgBase = (T)deserializedBody;
  return msgBase;
}

回答by ckross01

If the intent is to only grab the message body regardless of the content you can get it as a stream.

如果意图是只获取消息正文而不管内容如何,​​您都可以将其作为流获取。

Stream stream = message.GetBody<Stream>();
StreamReader reader = new StreamReader(stream);
string s = reader.ReadToEnd();

回答by Vitaliy Markitanov

In sample before ContentType utilized to detect body type. I believe ContentType should be set by sender. I do similar logic, I set one of message properties to type of object on sender side and call GetBody<>() on receiver with type retrived from message property. like this:

在用于检测身体类型的 ContentType 之前的示例中。我相信 ContentType 应该由发件人设置。我做了类似的逻辑,我将消息属性之一设置为发送方的对象类型,并使用从消息属性检索的类型在接收方上调用 GetBody<>() 。像这样:

public void SendData(object payloadData)
    {
        if (payloadData == null) return;

        var queueClient = QueueClient.CreateFromConnectionString(ConnectionString, _queueName);

        var brokeredMessage = new BrokeredMessage(payloadData);
        brokeredMessage.Properties["messageType"] = payloadData.GetType().AssemblyQualifiedName;
        queueClient.Send(brokeredMessage);
    }

Message property "messageType" has full name of type.

消息属性“messageType”具有类型的全名。

On receiving side I do like this:

在接收方,我喜欢这样:

 var messageBodyType = Type.GetType(receivedMessage.Properties["messageType"].ToString());
                if (messageBodyType == null)
                {
                    //Should never get here as a messagebodytype should
                    //always be set BEFORE putting the message on the queue
                    Trace.TraceError("Message does not have a messagebodytype" +
                                     " specified, message {0}", receivedMessage.MessageId);
                    receivedMessage.DeadLetter();
                }


                //read body only if event handler hooked
                    var method = typeof(BrokeredMessage).GetMethod("GetBody", new Type[] { });
                    var generic = method.MakeGenericMethod(messageBodyType);
                    try
                    {
                        var messageBody = generic.Invoke(receivedMessage, null);
                         DoSomethingWithYourData();
                        receivedMessage.Complete();
                    }
                    catch (Exception e)
                    {
                        Debug.Write("Can not handle message. Abandoning.");
                        receivedMessage.Abandon();
                    }
                }