2012-09-26 32 views
3

我正在嘗試使用ClientMessageInspector修改來自Web Service的響應。在某些時候,我需要從修改後的XMLStream創建一個Message。流的含量低於:在WCF中修改XML響應;破解XML

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

如何防止「...... stream ...」並獲取實際的XML部分?

回答

3

XmlReader創建的消息總是會打印出...stream...作爲其正文。由於閱讀器是底層XML的唯一向前視圖,因此不能多次使用,因此如果ToString要從閱讀器讀取數據,則該消息將無法被WCF管道的其餘部分使用(如編碼器,將其寫入導線)。

如果你真的想看到完整的信息,你可以做的是自己緩衝信息,然後重新創建。你可以使用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 
    } 
}