2011-10-11 9 views
2

所以我相信我理解的概念,我想我應該用IClientMessageInspector,但在我看來,所有的工具,我有一個System.ServiceModel.Channels.Message的身體工作需要使用.NET中的XML對象,我不能這樣做,因爲, ,此消息的正文是非法的XML。最終,該消息是這樣的:如何在非法XML時清除服務的響應?

[random number] 
<validXml /> 
[other random number] 

例如:

379 
<?xml version="1.0" encoding="UTF-8"?> 
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
<soapenv:Body soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> 
    <ns1:getVersionResponse> 
    <ns1:getVersionResponse xsi:type="xsd:string">1.2.3</ns1:getVersionResponse> 
    </ns1:getVersionResponse> 
</soapenv:Body> 
</soapenv:Envelope> 
0 

這裏是將除了事實的工作,例如,上面是無效的XML(正是我的原因首先這樣做)!

public class CleanRandomNumbersInspector : IClientMessageInspector 
{ 
    public void AfterReceiveReply(ref Message reply, object correlationState) 
    { 
     const int tenMegabytes = 10485760; 
     var buffer = reply.CreateBufferedCopy(tenMegabytes); 
     var copyToRead = buffer.CreateMessage(); 
     string body; 

     using (var reader = copyToRead.GetReaderAtBodyContents()) 
     { 
      body = reader.ReadOuterXml(); 
     } 

     // Now that we have the text, modify it 
     body = body.Trim('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0'); 

     // Shove it back into the message 
     var copyToPassOn = buffer.CreateMessage(); 
     using (var stream = GenerateStreamFromString(body)) 
     { 
      var writer = XmlDictionaryWriter.CreateTextWriter(stream); 
      copyToPassOn.WriteBodyContents(writer); 
     } 

     // Implement this method to inspect/modify messages after a message 
     // is received but prior to passing it back to the client 
     Console.WriteLine("AfterReceiveReply called"); 
    } 

    public object BeforeSendRequest(ref Message request, IClientChannel channel) 
    { 
     // GNDN 
     return null; 
    } 

    private static Stream GenerateStreamFromString(string s) 
    { 
     var stream = new MemoryStream(); 
     var writer = new StreamWriter(stream); 
     writer.Write(s); 
     writer.Flush(); 
     stream.Position = 0; 
     return stream; 
    } 
} 

歸根結底,是的,我知道,這是一個糟糕的服務。然而,在另一方解決這個問題之前,我需要消耗它。我怎樣才能做到這一點?

回答

2

您可以通過使用自定義消息編碼器(包裝原始編碼器,並在MessageEncoder.ReadMessage的實現中,在將主體移交給原始編碼器之前刪除任何無關字節)來完成此操作。

但是,這是非常糟糕的XML?這看起來像是分塊傳輸編碼(請參閱http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html,第3.6.1節) - 檢查HTTP標頭以查看是否找到Transfer-Encoding: chunked標頭,然後由HTTP傳輸去除這些塊。 WCF中的HTTP傳輸可以處理那些,你在哪裏看到這個問題?

+0

嗯,你在這裏的東西。事實上,那個標題就在那裏。我所看到的是儘管服務返回了XML(帶有這些額外的位),但我的代理始終爲我提供了一個由服務方法返回的NULL對象,而不是任何類型的對象。我手動生成的代理沒有太多天賦('svcutil http://service.url?wsdl/l:cs/config:my.config')。當我開始調查爲什麼我的回答總是NULL時,「無效XML」是我的結論。所以我想是時候回過頭去調查爲什麼我的代理總是返回NULL ... – Jaxidian

+0

對於它的價值,我相信這個第三方Web服務有一些搞砸的命名空間。 Ughh ..... – Jaxidian

1

我不認爲你將能夠做到這一點你的.NET應用程序的內部,而不完全繞開這些API。

我的建議是你自己寫的一個小幫手代理服務這個Web服務,它加載它,剝去垃圾,輸出有效的XML。

然後你的主要的應用程序將能夠從您的代理服務器作爲一個正常的XML SOAP服務讀它,也不會需要了解他們發送惡意代碼的任何東西。

然後當他們這樣做修復服務本身,你可以簡單地改變你的應用程序的URL回原來的一個,並且關閉您的代理;您的主應用程序不需要更改代碼,但是之後也不會留下冗餘代碼。

+0

真的嗎?這太令人失望的WCF ...... – Jaxidian

+0

嗯,麻煩的是API(至少我用過的那些)接受服務URL,並給你格式化的數據,而不用你的代碼來查看實際的XML字符串。所以你沒有機會在驗證和解析之前調整XML字符串。 – Spudley

相關問題