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>
どちらの場合も、要素の子として空の詳細要素があります<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 1.1 応答と同じで<soap:Detail>
あるだけです。<detail>
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 修飾名をハードコーディングする必要がありますか?