2009-08-23 112 views
2

我有一個消息合同,我傳遞給我的wcf服務,我有一個消息檢查器,我正在使用它來查找wcf客戶端發送的內容。 我有消息,但我不知道如何從中獲取數據。 以下是我正在傳遞給wcf服務的消息請求。如何從System.ServiceModel.Channels.Message獲取消息內容?

[MessageContract] 
public class MyMessageRequest 
{ 
    [MessageBodyMember] 
    public string Response 
    { 
     get; 
     set; 
    } 

    [MessageHeader] 
    public string ExtraValues 
    { 
     get; 
     set; 
    } 
} 

的方法,其中我得到的消息是以下幾點:

public object AfterReceiveRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel, System.ServiceModel.InstanceContext instanceContext) 
{ 
     MessageBuffer buffer = request.CreateBufferedCopy(Int32.MaxValue); 

     request = buffer.CreateMessage(); 
     Console.WriteLine("Received:\n{0}", buffer.CreateMessage().ToString()); 
     return null; 
} 

我想看到的響應值和ExtraValues出來的消息, 請人幫我在這。

回答

3

我想你想

http://msdn.microsoft.com/en-us/library/system.servicemodel.description.typedmessageconverter.frommessage.aspx

其中

(new TypedMessageConverter<MyMessageRequest>()).FromMessage(msg) 

會給你回你所需要的對象。

+1

我沒有找到任何通用TypedMessageConverter。它在哪裏,可以告訴我名字空間嗎? – 2009-08-23 18:30:14

+1

命名空間出現在鏈接的文檔頁面(System.ServiceModel.Description)的URL和頂部。 – Brian 2009-08-23 21:50:02

2

我在Microsoft的Message.ToString()實現中發現了一個弱點。 然後我找出原因並找到了解決辦法。

Message.ToString()可能的正文內容爲「... stream ...」。

這意味着消息是使用從尚未讀取的Stream創建的XmlRead或XmlDictionaryReader創建的。

ToString被記錄爲不改變消息的狀態。 因此,他們不會讀取流,只是放入一個標記。由於我的目標是(1)獲取字符串,(2)改變字符串,(3)從改變的字符串中創建一個新的消息,我需要做一點額外的工作。

這就是我想出了:

/// <summary> 
/// Get the XML of a Message even if it contains an unread Stream as its Body. 
/// <para>message.ToString() would contain "... stream ..." as 
///  the Body contents.</para> 
/// </summary> 
/// <param name="m">A reference to the <c>Message</c>. </param> 
/// <returns>A String of the XML after the Message has been fully 
///   read and parsed.</returns> 
/// <remarks>The Message <paramref cref="m"/> is re-created 
///   in its original state.</remarks> 
String MessageString(ref Message m) 
{ 
    // copy the message into a working buffer. 
    MessageBuffer mb = m.CreateBufferedCopy(int.MaxValue); 

    // re-create the original message, because "copy" changes its state. 
    m = mb.CreateMessage(); 

    Stream s = new MemoryStream(); 
    SmlWriter xw = CmlWriter.Create(s); 
    mb.CreateMessage().WriteMessage(xw); 
    xw.Flush(); 
    s.Position = 0; 

    byte[] bXML = new byte[s.Length]; 
    s.Read(bXML, 0, s.Length); 

    // sometimes bXML[] starts with a BOM 
    if (bXML[0] != (byte)'<') 
    { 
     return Encoding.UTF8.GetString(bXML,3,bXML.Length-3); 
    } 
    else 
    { 
     return Encoding.UTF8.GetString(bXML,0,bXML.Length); 
    } 
} 
/// <summary> 
/// Create an XmlReader from the String containing the XML. 
/// </summary> 
/// <param name="xml">The XML string o fhe entire SOAP Message.</param> 
/// <returns> 
///  An XmlReader to a MemoryStream to the <paramref cref="xml"/> string. 
/// </returns> 
XmlReader XmlReaderFromString(String xml) 
{ 
    var stream = new System.IO.MemoryStream(); 
    // NOTE: don't use using(var writer ...){...} 
    // because the end of the StreamWriter's using closes the Stream itself. 
    // 
    var writer = new System.IO.StreamWriter(stream); 
    writer.Write(xml); 
    writer.Flush(); 
    stream.Position = 0; 
    return XmlReader.Create(stream); 
} 
/// <summary> 
/// Creates a Message object from the XML of the entire SOAP message. 
/// </summary> 
/// <param name="xml">The XML string of the entire SOAP message.</param> 
/// <param name="">The MessageVersion constant to pass in 
///    to Message.CreateMessage.</param> 
/// <returns> 
///  A Message that is built from the SOAP <paramref cref="xml"/>. 
/// </returns> 
Message CreateMessageFromString(String xml, MessageVersion ver) 
{ 
    return Message.CreateMessage(XmlReaderFromString(xml), ver); 
} 

-Jesse