私は、FaultException と FaultException<T> を使用して、アプリケーションでの最適な使用パターンを判断しようとしています。SOAP 1.1 クライアントや SOAP 1.2 クライアントなど、WCF だけでなく、WCF 以外のサービス コンシューマー/クライアントもサポートする必要があります。
参考までに: FaultExceptions を wsHttpBinding で使用すると SOAP 1.2 セマンティクスになりますが、FaultExceptions を basicHttpBinding で使用すると SOAP 1.1 セマンティクスになります。
次のコードを使用して、FaultException<FaultDetails> をスローしています。
throw new FaultException<FaultDetails>(
new FaultDetails("Throwing FaultException<FaultDetails>."),
new FaultReason("Testing fault exceptions."),
FaultCode.CreateSenderFaultCode(new FaultCode("MySubFaultCode"))
);
FaultDetails クラスは、以下に示すように、文字列 "Message" プロパティを含む単純なテスト クラスです。
wsHttpBinding を使用する場合の応答は次のとおりです。
<?xml version="1.0" encoding="utf-16"?>
<Fault xmlns="http://www.w3.org/2003/05/soap-envelope">
<Code>
<Value>Sender</Value>
<Subcode>
<Value>MySubFaultCode</Value>
</Subcode>
</Code>
<Reason>
<Text xml:lang="en-US">Testing fault exceptions.</Text>
</Reason>
<Detail>
<FaultDetails xmlns="http://schemas.datacontract.org/2004/07/ClassLibrary" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Message>Throwing FaultException<FaultDetails>.</Message>
</FaultDetails>
</Detail>
これは、SOAP 1.2 仕様によると正しく見えます。メイン/ルートの「コード」は「送信者」で、「サブコード」は「MySubFaultCode」です。サービス コンシューマー/クライアントが WCF を使用している場合、クライアント側の FaultException も同じ構造を模倣し、faultException.Code.Name は「Sender」、faultException.Code.SubCode.Name は「MySubFaultCode」になります。
basicHttpBinding を使用する場合の応答は次のとおりです。
<?xml version="1.0" encoding="utf-16"?>
<s:Fault xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<faultcode>s:MySubFaultCode</faultcode>
<faultstring xml:lang="en-US">Testing fault exceptions.</faultstring>
<detail>
<FaultDetails xmlns="http://schemas.datacontract.org/2004/07/ClassLibrary" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Message>Throwing FaultException<FaultDetails>.</Message>
</FaultDetails>
</detail>
</s:Fault>
これは正しくありません。SOAP 1.1 の仕様を見て、FaultCode.CreateSenderFaultCode(new FaultCode("MySubFaultCode")) を使用すると、「faultcode」の値が「s:Client.MySubFaultCode」になると予想していました。また、WCF クライアントは正しくない構造を取得します。faultException.Code.Name は「Sender」ではなく「MySubFaultCode」であり、faultException.Code.SubCode は faultException.Code.SubCode.Name が「MySubFaultCode」ではなく null です。また、faultException.Code.IsSenderFault は false です。
FaultCode.CreateReceiverFaultCode(new FaultCode("MySubFaultCode")) を使用した場合の同様の問題:
- SOAP 1.2 では期待どおりに動作します
- 「s:Server.MySubFaultCode」の代わりに「s:MySubFaultCode」を生成し、SOAP 1.1 の faultException.Code.IsReceiverFault は false です。
この項目は、2006 年にhttp://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=669420&SiteID=1に他の人によって投稿されたもので、誰も回答していません。まだ誰もこれに遭遇していないとは信じがたいです。
同様の問題を抱えている他の人がいます:http://forums.microsoft.com/msdn/ShowPost.aspx?PostID=3883110&SiteID=1&mode=1
Microsoft Connect のバグ: https://connect.microsoft.com/wcf/feedback/ViewFeedback.aspx?FeedbackID=367963
障害がどのように機能するかの説明: http://blogs.msdn.com/drnick/archive/2006/12/19/creating-faults-part-3.aspx
私は何か間違ったことをしていますか、それとも本当に WCF のバグですか?