【问题标题】:Get body from WCF message从 WCF 消息中获取正文
【发布时间】:2011-05-22 22:22:22
【问题描述】:

我在从 wcf 消息中检索正文时遇到了一些问题。我正在尝试实现 WCF 消息检查器来验证针对 XSD 架构的消息。

肥皂体如下所示:

<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <Header xmlns="http://www.test1.com">
      <applicationID>1234</applicationID>
    </Header>
    <GetMatchRequest xmlns="http://www.tempuri.org">test</GetMatchRequest>
  </s:Body>

问题是当我尝试获取正文时,它只会收到部分正文消息。只获取 header 元素,忽略 GetMatchRequest 元素(可能是因为多个命名空间...)

我正在使用以下获取消息正文:

XmlDocument bodyDoc = new XmlDocument();
bodyDoc.Load( message.GetReaderAtBodyContents().ReadSubtree());

我也尝试了以下方法:

bodyDoc.Load( message.GetReaderAtBodyContents());

上面的代码导致错误 - 此文档已经有一个“DocumentElement”节点。

谁能帮忙从 WCF 消息中提取正文?

谢谢

【问题讨论】:

  • 请向我们展示您的服务合同是什么样的。通常,您无需担心 SOAP 会通过网络传输。 WCF 将其抽象化,因此您可以处理对象调用等。
  • 为什么您觉得需要验证 XML?如果将无效的 XML 发送到您的服务,您认为会发生什么?您认为哪种代码会向您发送无效的 XML,如果您告诉它 XML 无效,您认为该代码会做什么?

标签: wcf


【解决方案1】:

Message.GetReaderAtBodyContents 返回的阅读器不是位于元素处,而是位于其第一个子元素处。通常消息正文只包含一个根元素,因此您可以直接加载它。但是在您的消息中它包含多个根元素(Header 和 GetMatchRequest),因此如果您想在 XmlDocument 中加载整个正文,您需要提供一个包装元素(XmlDocument 只能有一个根元素)。在下面的示例中,我使用&lt;s:Body&gt; 作为包装元素,但您可以使用任何您想要的东西。代码只是读取正文,直到找到结束元素 (&lt;/s:Body&gt;)。

    public class Post_a866abd2_bdc2_4d30_8bbc_2ce46df38dc4
    {
        public static void Test()
        {
            string xml = @"<s:Envelope xmlns:s=""http://schemas.xmlsoap.org/soap/envelope/"">
  <s:Body xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"">
    <Header xmlns=""http://www.test1.com"">
      <applicationID>1234</applicationID>
    </Header>
    <GetMatchRequest xmlns=""http://www.tempuri.org"">test</GetMatchRequest>
  </s:Body>
</s:Envelope>";
            Message message = Message.CreateMessage(XmlReader.Create(new StringReader(xml)), int.MaxValue, MessageVersion.Soap11);
            Console.WriteLine(message);
            XmlDocument bodyDoc = new XmlDocument();
            MemoryStream ms = new MemoryStream();
            XmlWriter w = XmlWriter.Create(ms, new XmlWriterSettings { Indent = true, IndentChars = "  ", OmitXmlDeclaration = true });
            XmlDictionaryReader bodyReader = message.GetReaderAtBodyContents();
            w.WriteStartElement("s", "Body", "http://schemas.xmlsoap.org/soap/envelope/");
            while (bodyReader.NodeType != XmlNodeType.EndElement && bodyReader.LocalName != "Body" && bodyReader.NamespaceURI != "http://schemas.xmlsoap.org/soap/envelope/")
            {
                if (bodyReader.NodeType != XmlNodeType.Whitespace)
                {
                    w.WriteNode(bodyReader, true);
                }
                else
                {
                    bodyReader.Read(); // ignore whitespace; maintain if you want
                }
            }
            w.WriteEndElement();
            w.Flush();
            Console.WriteLine(Encoding.UTF8.GetString(ms.ToArray()));
            ms.Position = 0;
            XmlDocument doc = new XmlDocument();
            doc.Load(ms);
            Console.WriteLine(doc.DocumentElement.OuterXml);
        }
    }

【讨论】:

    猜你喜欢
    • 2010-12-15
    • 2012-09-09
    • 2011-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-22
    相关资源
    最近更新 更多