エラーの定義と指定

SOAP エラーを使用する目的は、エラー状態情報をサービスからクライアントに伝達し、双方向のシナリオでは、相互利用が可能な手段でクライアントからサービスにも伝達することです。 ここでは、カスタムのエラー コンテンツをいつどのように定義し、そのエラーを返す操作をどのように指定するかについて説明します。 サービスまたは双方向クライアントがエラーを送信する方法、およびクライアントまたはサービス アプリケーションがエラーを処理する方法について詳しくは、「エラーの送受信」を参照してください。 Windows Communication Foundation (WCF) アプリケーションでのエラー処理の概要については、「コントラクトおよびサービスのエラーの指定と処理」を参照してください。

概要

宣言された SOAP エラーは、カスタム SOAP エラーの種類を指定する System.ServiceModel.FaultContractAttribute を含む操作で発生します。 宣言されていない SOAP エラーとは、操作のコントラクトに指定されていないエラーです。 ここでは、各種のエラー状態を特定したうえで、サービスに関するエラー コントラクトを作成する方法について説明します。クライアントは、カスタムの SOAP エラーから通知を受けたときに、これらを使用することでエラーを適切に処理できます。 基本的なタスクは、次の順序で行います。

  1. サービスのクライアントに通知する必要があるエラー状態を定義します。

  2. そのエラー状態に対して SOAP エラーのカスタム コンテンツを定義します。

  3. 操作でスローされた特定の SOAP エラーがクライアントに公開されるように、WSDL でその操作にマークします。

クライアントに通知する必要があるエラー状態の定義

SOAP エラーは、特定の操作に関するフォールト情報を伝達するためにパブリックに記述されたメッセージです。 これらのメッセージは、WSDL で他の操作メッセージと共に記述されているので、クライアントは、操作を呼び出した時点でこのようなエラー処理を予測できます。 ただし、WCF サービスはマネージド コードで記述されています。マネージド コードで記述されたどのエラー状態をフォールトに変換し、クライアントに返す必要があるかを決定することによって、サービスのエラー状態やバグは、クライアントとの間でエラーに関して行われる正規のメッセージ交換から分離することができます。

たとえば、次のコード例には、2 つの整数を受け取り、別の整数を返す操作があります。 ここではいくつかの例外がスローされる可能性があります。そのため、エラー コントラクトを設計するときに、クライアントにとって重要なエラー状態を判別する必要があります。 この場合、サービスでは System.DivideByZeroException 例外を検出する必要があります。

[ServiceContract]  
public class CalculatorService  
{  
    [OperationContract]
    int Divide(int a, int b)  
    {  
      if (b==0) throw new Exception("Division by zero!");  
      return a/b;  
    }  
}  
<ServiceContract> _
Public Class CalculatorService
    <OperationContract> _
    Public Function Divide(a As Integer, b As Integer) As Integer
        If b = 0 Then Throw New DivideByZeroException("Division by zero!")
        Return a / b
    End Function
End Class

この例で操作から返せるエラーには、ゼロによる除算に特化したカスタム SOAP エラー、ゼロ除算に特化した情報が算術演算に特化したエラーに含まれているもの、複数の異なるエラー状態に対する複数のエラーなどがあります。SOAP エラーを返さないことも選択できます。

エラー状態のコンテンツの定義

意義のあるカスタム SOAP エラーを返すエラー状態を特定したら、次の手順では、そのエラーのコンテンツを定義し、コンテンツ構造をシリアル化できるようにします。 前のセクションのコード例では、Divide 演算に特化したエラーを示していました。しかし、Calculator サービスに他の演算がある場合、1 つのカスタム SOAP エラーで、Divide を含むすべての電卓エラー状態をクライアントに通知することも可能です。 次のコード例では、MathFault を含むすべての算術演算で生成されたエラーを報告するためのカスタム SOAP エラー Divide を作成しています。 このクラスでは、操作 (Operation プロパティ) と問題を説明する値 (ProblemType プロパティ) を指定できますが、カスタム SOAP エラーでクライアントに転送するには、クラスとこれらのプロパティがシリアル化可能である必要があります。 このため、System.Runtime.Serialization.DataContractAttribute 属性と System.Runtime.Serialization.DataMemberAttribute 属性を使用して、型とそのプロパティをシリアル化可能にし、できる限り相互運用可能にします。

// Define a math fault data contract
[DataContract(Namespace="http://Microsoft.ServiceModel.Samples")]
public class MathFault
{
    private string operation;
    private string problemType;

    [DataMember]
    public string Operation
    {
        get { return operation; }
        set { operation = value; }
    }

    [DataMember]
    public string ProblemType
    {
        get { return problemType; }
        set { problemType = value; }
    }
}
' Define a math fault data contract
<DataContract([Namespace]:="http://Microsoft.ServiceModel.Samples")> _
Public Class MathFault

    Private m_operation As String
    Private m_problemType As String

    <DataMember()> _
    Public Property Operation() As String

        Get

            Return m_operation

        End Get

        Set(ByVal value As String)

            m_operation = value

        End Set

    End Property

    <DataMember()> _
    Public Property ProblemType() As String

        Get

            Return m_problemType

        End Get

        Set(ByVal value As String)

            m_problemType = value

        End Set

    End Property

End Class

データをシリアル化可能にする方法について詳しくは、「サービス コントラクトでのデータ転送の指定」を参照してください。 System.Runtime.Serialization.DataContractSerializer で提供されるシリアル化サポートの一覧については、「データ コントラクト シリアライザーでサポートされる型」を参照してください。

エラー コントラクトを確立するための操作のマーク

カスタム SOAP エラーの一部として返されるシリアル化可能なデータ構造を定義したら、最後に、その型の SOAP エラーをスローできることを操作コントラクトにマークします。 これには、System.ServiceModel.FaultContractAttribute 属性を使用して、作成したカスタム データ型の型を渡します。 FaultContractAttribute 属性を使用して、Divide 操作で MathFault 型の SOAP エラーを返すように指定する方法を次のコード例に示します。 他の算術に関する操作でも、MathFault を返せるように指定できます。

[OperationContract]
[FaultContract(typeof(MathFault))]
int Divide(int n1, int n2);
<OperationContract()> _
<FaultContract(GetType(MathFault))> _
Function Divide(ByVal n1 As Integer, ByVal n2 As Integer) As Integer

操作に複数の FaultContractAttribute 属性をマークすることによって、その操作で複数のカスタム エラーを返すことを指定できます。

操作実装にエラー コントラクトを実装する方法については、「エラーの送受信」を参照してください。

SOAP、WSDL、相互運用性に関する考慮事項

特に他のプラットフォームと相互運用するときなど、状況によっては、SOAP メッセージでエラーを表す方法または WSDL メタデータでエラーを記述する方法を制御することが重要な場合があります。

FaultContractAttribute 属性の Name プロパティを使用すると、エラーに対してメタデータで生成される WSDL エラー要素名を制御できます。

SOAP 標準に従って、エラーには、ActionCode、および Reason を指定することができます。 Action は、Action プロパティによって制御されます。 Code プロパティと Reason プロパティは、ジェネリック System.ServiceModel.FaultException の親クラスである System.ServiceModel.FaultException<TDetail> クラスのプロパティです。 Code プロパティには、SubCode メンバーが含まれています。

エラーを生成する非サービスを利用する場合には、特定の制限事項があります。 WCF では、スキーマによって記述され、データ コントラクトと互換性のある、詳細な型を持つエラーしかサポートされません。 たとえば、上記のように WCF では、詳細な型で XML 属性を使用するエラーや、詳細セクションに複数のトップレベル要素を持つエラーがサポートされていません。

関連項目