Как получить содержимое сообщения из System.ServiceModel.Channels.Message? - PullRequest
3 голосов
/ 23 августа 2009

У меня есть контракт на передачу сообщений, который я передаю своей службе wcf, и у меня есть инспектор сообщений, который я использую для поиска того, что было отправлено клиентом wcf. У меня есть Сообщение, но я не знаю, как получить из него данные. ниже мой запрос сообщения, который я передаю службе wcf.

[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;
}

Я хочу видеть значения Response и ExtraValues ​​из сообщения, Пожалуйста, кто-нибудь поможет мне в этом.

Ответы [ 2 ]

6 голосов
/ 25 мая 2012

Я нашел ошибку в реализации Microsoft Message.ToString (). Тогда я выяснил причину и нашел решение.

Message.ToString () может содержать содержимое тела в виде "... 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();
    XmlWriter xw = XmlWriter.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

3 голосов
/ 23 августа 2009

Я думаю, что вы хотите

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

, где

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

вернет вам нужный вам предмет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...