2009-08-23 98 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