ASP.Net 2.0 Web服务自动创建SOAP 1.1和SOAP 1.2绑定。但是,我们的Web服务具有SOAP扩展和自定义异常处理,它们假设只使用SOAP 1.1绑定(例如,SOAP扩展使用HTTP SOAPAction标头来控制行为)。
我希望纠正做出这些假设的代码,使其能够正确地与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:Fault>
元素的子元素,但它具有不同的限定名,即<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响应现在具有错误的detail元素限定名。它应该是<soap:Detail>
,但实际上只是<detail>
,与SOAP 1.1响应相同。
看起来ASP.Net2.0框架在将SOAPException转换为适合SOAP版本的形式方面做了很多工作,但却忽略了正确处理detail元素。此外,它们似乎没有像处理SoapException.DetailElementName属性那样为detail元素公开正确的SOAP 1.2限定名。
那么,将detail元素添加到同时适用于SOAP 1.1和SOAP 1.2的SOAP错误响应中的正确方法是什么呢?我是否需要自己检测SOAP版本并为detail元素硬编码SOAP 1.2限定名?
3条答案
按热度按时间9w11ddsr1#
不知道你的问题的编码部分,对不起,但是一个解决办法是在你的web.config中禁用soap1.2,如果你还没有这样做的话。
rekjcdws2#
以下内容并非恶意中伤:
此问题的解决方法是使用WCF。
这看起来像是ASMX Web服务在处理SOAP 1.2错误中的detail元素时出现的错误。显然,根据元素是否具有值来更改元素的限定名是没有意义的。
您可以在Connect上报告此错误,但由于只修复了关键的ASMX错误,因此这不太可能对您有所帮助。
我怀疑WCF有这个问题,因为它完全支持SOAP故障。
8ftvxx2r3#
这是一个迟来的答案,但由于我自己也遇到过这个问题,所以我想我也可以在这里提出我的解决方案,它本质上是沿着SOAP协议的版本传递给构建错误消息的详细信息部分的方法。
从其派生ASMX Web服务类得WebService类公开SoapVersion属性,该属性包含用于发出当前SOAP请求得SOAP协议得版本.
然后可以轻松地生成适合当前SOAP版本的详细信息节。