3

我正在尝试使用 ClientMessageInspector 修改来自 Web 服务的响应。在某些时候,我需要Message从修改后的XMLStream. 流的内容如下:

<soapenv:Envelope xmlns:soapenv="http://env" xmlns:xsd="http://xsd" xmlns:xsi="http://xsi" xmlns:v1="http://v1">
    <soapenv:Body>
        <v1:VM>
            <SH>
                <a>aa</a>
                <b>bb</b>
            </SH>
        </v1:VM>
    </soapenv:Body>
</soapenv:Envelope>

我尝试使用以下方法创建消息:

System.Xml.XmlReader XMLReader = System.Xml.XmlReader.Create(XMLStream);
Message ModifiedReply = System.ServiceModel.Channels.Message.CreateMessage(OriginalReply.Version, null, XMLReader);

但是,当我使用 Message.ToString() 打印消息内容时,我得到:

<s:Envelope xmlns:s="http://env">
    <s:Header />
        <s:Body>
            ... stream ...
        </s:Body>
</s:Envelope>

如何防止“...流...”并获取实际的 XML 部分?

4

1 回答 1

3

从 a 创建的消息XmlReader将始终...stream...作为其正文打印出来。由于阅读器是底层 XML 的仅向前视图,因此不能多次使用它,因此如果ToString要从阅读器读取数据,则 WCF 管道的其余部分将无法使用该消息(例如编码器,它将把它写到电线上)。

如果你真的想看到完整的消息,你可以做的是自己缓冲消息,然后再重新创建它。你可以使用 a MessageBuffer。如果您真的想要完整的消息内容,ToString可能会也可能不会给您,因此您需要将消息写出来以强制打印。

public class StackOverflow_12609525
{
    public static void Test()
    {
        string xml = @"<soapenv:Envelope xmlns:soapenv=""http://schemas.xmlsoap.org/soap/envelope/""
            xmlns:xsd=""http://xsd""
            xmlns:xsi=""http://xsi""
            xmlns:v1=""http://v1"">
        <soapenv:Body>
            <v1:VM>
                <SH>
                    <a>aa</a>
                    <b>bb</b>
                </SH>
            </v1:VM>
        </soapenv:Body>
    </soapenv:Envelope>";
        MemoryStream XmlStream = new MemoryStream(Encoding.UTF8.GetBytes(xml));
        XmlReader reader = XmlReader.Create(XmlStream);
        Message originalReply = Message.CreateMessage(reader, int.MaxValue, MessageVersion.Soap11);
        Console.WriteLine(originalReply); // this shows ...stream...
        Console.WriteLine();

        XmlStream = new MemoryStream(Encoding.UTF8.GetBytes(xml));
        reader = XmlReader.Create(XmlStream);

        Message modifiedReply = Message.CreateMessage(reader, int.MaxValue, originalReply.Version);
        MessageBuffer buffer = modifiedReply.CreateBufferedCopy(int.MaxValue); // this consumes the message

        Message toPrint = buffer.CreateMessage();
        MemoryStream ms = new MemoryStream();
        XmlWriterSettings ws = new XmlWriterSettings
        {
            Indent = true,
            IndentChars = "  ",
            OmitXmlDeclaration = true,
            Encoding = new UTF8Encoding(false)
        };
        XmlWriter w = XmlWriter.Create(ms, ws);
        toPrint.WriteMessage(w);
        w.Flush();
        Console.WriteLine(Encoding.UTF8.GetString(ms.ToArray()));

        modifiedReply = buffer.CreateMessage(); // need to recreate the message here
    }
}
于 2012-09-26T20:30:34.437 回答