コントラクトおよびサービスのエラーの指定と処理
Windows Communication Foundation (WCF) アプリケーションで、エラー状態を処理するには、マネージド例外オブジェクトを SOAP エラー オブジェクトにマップし、SOAP エラー オブジェクトをマネージド例外オブジェクトにマップします。 ここでは、エラー状態がカスタムの SOAP エラーとして公開されるようにコントラクトを設計する方法、そのエラーをサービス実装の一部として返す方法、およびクライアントがそのエラーをキャッチする方法を説明します。
エラー処理の概要
すべてのマネージド アプリケーションで、操作エラーは Exception オブジェクトにより表されます。 WCF アプリケーションなどの SOAP に基づくアプリケーション内のサービス メソッドからは、SOAP エラー メッセージを使用して操作エラー情報が通知されます。 SOAP エラーは、サービス操作のメタデータに含まれるメッセージ型です。これにより、クライアントが操作を堅牢かつインタラクティブにするために使用できるエラー コントラクトを作成できます。 また、SOAP エラーは XML 形式でクライアントに伝達されるので、この型システムは相互運用性が高く、あらゆる SOAP プラットフォーム上のクライアントが使用できます。これによって、ユーザーの WCF アプリケーションの適用範囲が拡大します。
WCF アプリケーションは、両方の型のエラー システムで実行されるので、クライアントに送信されるマネージド例外情報は、サービス上で例外から SOAP エラーに変換し、送信後、WCF クライアントで SOAP エラーからエラー例外に変換する必要があります。 双方向クライアントの場合は、クライアント コントラクトによって SOAP エラーがサービスに返送されることもあります。 いずれの場合も、開発者は、既定のサービス例外の動作を使用することも、例外をエラー メッセージにマップするかどうかを制御することも (その場合はどのようにマップするかを指定することも) できます。
送信できる SOAP エラーには次の 2 種類があります: 宣言されたものと宣言されていないもの。 宣言された SOAP エラーは、カスタム SOAP エラーの種類を指定する System.ServiceModel.FaultContractAttribute 属性を含む操作で発生します。 宣言されていない SOAP エラーは、操作のコントラクトに指定されていません。
FaultContractAttribute 属性を使用して、通常の操作中に受信することをクライアントが予期できるすべての SOAP エラーを正式に指定することによって、サービス操作でそのエラーを宣言することを強くお勧めします。 また、SOAP エラーでは、情報の漏えいを最小限に抑えるために、クライアントが知る必要がある情報だけを返すことをお勧めします。
通常、サービス (および双方向クライアント) は、次の手順に従ってエラー処理をアプリケーションに統合します。
例外状態をカスタム SOAP エラーにマップします。
クライアントとサービスは、SOAP エラーを例外として送受信します。
また、WCF のクライアントとサービスでは、デバッグの目的で宣言されていない SOAP エラーを使用でき、既定のエラー動作を拡張できます。 以下のセクションで、これらのタスクと概念について説明します。
SOAP エラーへの例外のマッピング
エラー状態の処理操作を作成するための最初の手順は、クライアント アプリケーションにエラーを通知する状態を決定することです。 一部の操作には、その機能に固有のエラー状態があります。 たとえば、PurchaseOrder
操作では、発注書の作成が禁止になっている顧客に特定の情報を返すことができます。 また、Calculator
サービスなどでは、より一般的な MathFault
SOAP エラーを使用してサービス全体のすべてのエラー状態を記述できます。 サービスのクライアントのエラー状態を特定したら、カスタム SOAP エラーを作成し、エラー状態が発生したときに SOAP エラーを返す操作として、対応する操作をマークします。
サービスまたはクライアントのこの開発手順の詳細については、「エラーの定義と指定」を参照してください。
クライアントとサービスによる例外としての SOAP エラーの処理
操作エラー状態を特定し、カスタム SOAP エラーを定義し、そのようなエラーを返す操作にマークすることは、WCF アプリケーションで正常にエラーを処理するための最初の手順です。 次の手順では、このエラーの送受信を適切に実装します。 通常は、サービスがエラーを送信してクライアント アプリケーションにエラー状態を通知しますが、双方向クライアントが SOAP エラーをサービスに送信することもできます。
詳細については、「エラーの送受信」を参照してください。
非宣言 SOAP エラーとデバッグ
宣言 SOAP エラーは、堅牢で相互運用可能な分散アプリケーションを構築するうえで便利です。 ただし、サービス (または双方向クライアント) が非宣言 SOAP エラーを送信することが役立つ場合があります。非宣言 SOAP エラーとは、その操作について Web サービス記述言語 (WSDL) で宣言されていないエラーです。 たとえば、サービスの開発時に予期しない状況が発生する可能性があります。この場合、デバッグのために情報をクライアントに送信することが役立ちます。 また、ServiceBehaviorAttribute.IncludeExceptionDetailInFaults プロパティまたは ServiceDebugBehavior.IncludeExceptionDetailInFaults プロパティを true
に設定して、WCF クライアントが内部のサービス操作例外に関する情報を取得できるようにすることができます。 個別のエラー送信とデバッグ動作プロパティの設定については、「エラーの送受信」を参照してください。
重要
マネージド例外によって内部アプリケーション情報が公開されるおそれがあるため、ServiceBehaviorAttribute.IncludeExceptionDetailInFaults または ServiceDebugBehavior.IncludeExceptionDetailInFaults を true
に設定すると、個人の身元を確認できる情報またはその他の機密情報を含む内部サービス操作例外に関する情報を WCF クライアントで取得できるようになります。
したがって、ServiceBehaviorAttribute.IncludeExceptionDetailInFaults または ServiceDebugBehavior.IncludeExceptionDetailInFaults を true
に設定することは、サービス アプリケーションを一時的にデバッグする方法としてのみお勧めできます。 さらに、このようにして未処理のマネージド例外を返すメソッドの WSDL には、FaultException<TDetail> 型の ExceptionDetail のコントラクトが含まれません。 クライアントは、デバッグ情報を適切に取得するために、(System.ServiceModel.FaultException オブジェクトとして WCF クライアントに返される) 不明な SOAP エラーの可能性について想定しておく必要があります。
IErrorHandler によるエラー処理のカスタマイズ
アプリケーション レベルの例外が発生した場合にクライアントへの応答メッセージをカスタマイズする、または応答メッセージが返された後に何らかのカスタム処理を実行するという特別な要件がある場合は、System.ServiceModel.Dispatcher.IErrorHandler インターフェイスを実装します。
エラーのシリアル化の問題
WCF では、エラー コントラクトを逆シリアル化する場合、最初に SOAP メッセージのエラー コントラクト名とエラー コントラクトの型を一致させようとします。 正しく一致しない場合、使用可能なエラー コントラクトのアルファベット順のリストで互換性のある型を検索します。 2 つのエラー コントラクトが互換性のある型である場合 (たとえば、一方のコントラクトが別のコントラクトのサブクラスである場合)、エラーを逆シリアル化するときに間違った型が使用される場合があります。 このような問題は、エラー コントラクトで名前、名前空間、およびアクションが指定されていない場合に発生します。 このような問題が発生しないようにするには、常に名前、名前空間、およびアクションの属性を指定して、エラー コントラクトを完全修飾するようにしてください。 また、共有基本クラスから派生した関連エラー コントラクトを定義している場合は、新しいメンバーを [DataMember(IsRequired=true)]
でマークしてください。 この IsRequired
属性の詳細については、「DataMemberAttribute」を参照してください。 この結果、基本クラスに互換性のある型が指定されなくなり、正しい派生型にエラーが逆シリアル化されます。