2009-08-23 8 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. Где это, можете ли вы рассказать мне пространство имен? –

+1

Пространство имен отображается как в URL-адресе, так и в верхней части страницы документации, с которой я связан (System.ServiceModel.Description). – Brian

2

Я нашел уязвимость в реализации Microsoft Message.ToString(). Затем я понял причину и нашел решение.

Message.ToString() май имеет содержание тела как «... поток ...».

Это означает, что сообщение было создано с использованием XmlRead или XmlDictionaryReader, созданного из потока, который еще не был прочитан.

ToString зарегистрирован как НЕ изменяющий состояние сообщения. Итак, они не читают Stream, просто поставьте маркер, который включен.

Поскольку моя цель состояла в том, чтобы (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

Смежные вопросы