2011-05-22 59 views
1

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

SOAP体看起来像以下:

<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> 

问题是,当我试图让身体只得到部分机构留言。仅获取头元素,忽略GetMatchRequest元素(可能是因为多个命名空间的...)

我使用下面进入正文:

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

我也曾尝试以下操作:

bodyDoc.Load(message.GetReaderAtBodyContents()); 

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

任何人都可以请求从WCF消息中提取正文的帮助吗?

感谢

+0

请告诉我们您的服务合约是什么样的。一般来说,你不需要担心SOAP通过网络。 WCF将这些内容抽象出来,以便您可以处理对象调用等。 – 2011-05-22 22:32:12

+0

为什么你觉得你需要验证XML?如果将无效的XML发送到您的服务中,您认为会发生什么?你认为什么样的代码会向你发送无效的XML,如果你告诉它该XML无效,你认为这些代码会做什么? – 2011-05-22 23:34:11

回答

6

Message.GetReaderAtBodyContents返回的元素没有定位的阅读器,但在它的第一个孩子。通常消息体只包含一个根元素,所以你可以直接加载它。但是在你的消息中它包含了多个根元素(Header和GetMatchRequest),所以如果你想在XmlDocument中加载整个主体,你需要提供一个包装元素(XmlDocument只能有一个根元素)。在下面的示例中,我使用<s:Body>作为包装元素,但您可以使用任何您想要的东西。代码只是读取主体直到找到结束元素(</s:Body>)。

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); 
     } 
    } 
+0

谢谢卡洛斯!有效。 – user438975 2011-05-24 05:03:45