ASP.Net 2.0 Web服務自動創建SOAP 1.1和SOAP 1.2綁定。然而,我們的Web服務具有SOAP擴展和自定義異常處理,它們假定只使用SOAP 1.1綁定(例如,SOAP擴展使用HTTP SOAPAction頭來控制行爲)。ASP.Net Web服務 - 將細節元素添加到同時適用於SOAP 1.1和SOAP 1.2的SOAP錯誤響應的正確方法是什麼?
我正在尋找糾正這些假設的代碼,並使其適用於SOAP 1.1或SOAP 1.2。我在爲SOAP錯誤生成元素時遇到了一些問題。
考慮以下web方法實現:
[WebMethod]
public void
ThrowsSoapException()
{
throw new SoapException("This is a SOAP exception.", SoapException.ServerFaultCode);
}
經由SOAP調用此1.1產生以下結果:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<soap:Fault>
<faultcode>soap:Server</faultcode>
<faultstring>This is a SOAP exception.</faultstring>
<detail/>
</soap:Fault>
</soap:Body>
</soap:Envelope>
經由SOAP 1.2調用產生以下結果:
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<soap:Fault>
<soap:Code>
<soap:Value>soap:Receiver</soap:Value>
</soap:Code>
<soap:Reason>
<soap:Text xml:lang="en">This is a SOAP exception.</soap:Text>
</soap:Reason>
<soap:Detail/>
</soap:Fault>
</soap:Body>
</soap:Envelope>
在這兩種情況下,都有一個空的細節元素作爲的子項元素,但它具有不同的限定名稱,即<detail>
或<soap:Detail>
。
現在考慮下面的代碼,它試圖用detail元素創建一個SOAPException。
[WebMethod]
public void
ThrowsSoapExceptionWithDetail()
{
XmlDocument doc = new XmlDocument();
XmlNode detail =
doc.CreateNode(XmlNodeType.Element, SoapException.DetailElementName.Name, SoapException.DetailElementName.Namespace);
XmlNode custom =
doc.CreateNode(XmlNodeType.Element, "custom", "http://example.com/xml/namespace/blah");
custom.InnerXml = "Detail value";
detail.AppendChild(custom);
throw new SoapException("This is a SOAP exception with a detail element.", SoapException.ServerFaultCode, Context.Request.Url.AbsoluteUri, detail);
}
的SOAP 1.1響應爲:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<soap:Fault>
<faultcode>soap:Server</faultcode>
<faultstring>This is a SOAP exception with a detail element.</faultstring>
<faultactor>http://localhost/simplewebservice/service1.asmx</faultactor>
<detail>
<custom xmlns="http://example.com/xml/namespace/blah">Detail value</custom>
</detail>
</soap:Fault>
</soap:Body>
</soap:Envelope>
和SOAP 1.2的響應爲:
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<soap:Fault>
<soap:Code>
<soap:Value>soap:Receiver</soap:Value>
</soap:Code>
<soap:Reason>
<soap:Text xml:lang="en">This is a SOAP exception with a detail element.</soap:Text>
</soap:Reason>
<soap:Node>http://localhost/simplewebservice/service1.asmx</soap:Node>
<detail>
<custom xmlns="http://example.com/xml/namespace/blah">Detail value</custom>
</detail>
</soap:Fault>
</soap:Body>
</soap:Envelope>
的SOAP 1.2響應目前對細節元件錯誤的限定名。它應該是<soap:Detail>
,而只是<detail>
,與SOAP 1.1響應相同。
看來,ASP.Net 2.0框架已經做了相當多的工作,將SOAPException轉換爲SOAP版本的適當形式,但忽略了正確處理detail元素。此外,它們似乎沒有像使用SoapException.DetailElementName屬性一樣提供detail元素的正確SOAP 1.2限定名稱。
那麼,將細節元素添加到同時適用於SOAP 1.1和SOAP 1.2的SOAP錯誤響應的正確方法是什麼?我是否需要自己檢測SOAP版本並對detail元素的SOAP 1.2限定名稱進行硬編碼?
不幸的是,移除.Net 2.0目前是不可能的。 我也非常確定WCF將帶來自己的一套新問題,類似於我們已經在.asmx世界中使用自定義擴展等解決的問題。儘管如此,我一定想從長遠的角度來探索這個奢侈品。 – GBegen 2010-07-01 21:12:44
@GBegen:微軟在創建WCF時從ASMX的錯誤中學習是非常愚蠢的。特別是,可擴展性模型是_far_更清晰,更全面。除此之外,您可以接管整個服務的錯誤處理,並且可以根據需要覆蓋錯誤的序列化。除了它可能不需要,因爲WCF本身支持錯誤 - 一個WCF客戶端接收到一個故障響應,並且出現一個名爲'SomeFault'的錯誤,它會收到一個'FaultException'異常。 –
2010-07-02 00:09:17