2013-03-15 20 views
26

當您在Azure服務總線中使用代理郵件時,可以使用調用.GetBody檢索郵件正文。代碼很簡單:用azure brokeredmessage獲取身體而不知道類型

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

但是,有沒有一種方法來檢索身體沒有明確知道身體對象的類?

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

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

回答

27

下面是完整的代碼從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; 
} 
+2

這取決於brokeredMessage.ContentType。如果我們只是發送字符串,這個屬性可能會或可能不會被設置。有什麼方法可以識別它的簡單字符串,流或類類型嗎? – 2013-06-25 14:03:31

+0

此答案幫助解決了Azure中的WebWorkerRole上的GetBody ()嘗試訪問中介消息正文的序列化錯誤。謝謝。 – TombMedia 2013-07-02 09:41:34

+0

@Joymon不知道這是否是好的做法,但可以在發送消息時設置ContentType:var message = new BrokeredMessage(request); message.ContentType = request.GetType()。Name; – Dunc 2015-05-06 18:34:41

55

如果意圖是隻抓取郵件正文而不管內容是什麼,那麼您可以將它作爲一個流獲取。

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

尼斯小費!這應該是MSDN文檔的一部分:) – 2013-11-08 16:51:48

+1

這對於Node內部操作系統也非常有用,您可能希望在郵件正文中發送JSON附件 – 2015-10-26 21:28:22

5

樣品之前的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屬性 「爲messageType」 有一個類型的全名。

在接收端我這樣做:

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(); 
        } 
       } 
+0

謝謝,先生!這正是我尋找的解決方案! – 2016-01-05 15:04:34

相關問題