エラー コントラクト

エラー コントラクトのサンプルでは、エラー情報をサービスからクライアントに通信する方法を示します。サンプルは、「入門サンプル」に基づき、内部例外をエラーに変換するいくつかの追加コードをサービスに追加しています。クライアントは 0 による除算を試行し、サービスを強制的にエラー状態にします。

ms752208.note(ja-jp,VS.100).gif注 :
このサンプルのセットアップ手順とビルド手順については、このトピックの最後を参照してください。

電卓コントラクトは、FaultContractAttribute が含まれるように変更されています。次のサンプル コードを参照してください。

[ServiceContract(Namespace="http://Microsoft.ServiceModel.Samples")]
public interface ICalculator
{
    [OperationContract]
    int Add(int n1, int n2);
    [OperationContract]
    int Subtract(int n1, int n2);
    [OperationContract]
    int Multiply(int n1, int n2);
    [OperationContract]
    [FaultContract(typeof(MathFault))]
    int Divide(int n1, int n2);
}

FaultContractAttribute 属性は、Divide 操作が型 MathFault のエラーを返すことができることを示します。シリアル化可能な任意の型のエラーが発生します。この場合、MathFault は次のようなデータ コントラクトになります。

[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; }
    }
}

0 による除算の例外が発生すると、Divide メソッドは FaultException 例外をスローします。次のサンプル コードを参照してください。この例外により、クライアントにエラーが送信されます。

public int Divide(int n1, int n2)
{
    try
    {
        return n1 / n2;
    }
    catch (DivideByZeroException)
    {
        MathFault mf = new MathFault();
        mf.operation = "division";
        mf.problemType = "divide by zero";
        throw new FaultException<MathFault>(mf);
    }
}

クライアント コードは、0 による除算を要求することで強制的にエラーを発生させます。このサンプルを実行する場合は、操作要求および応答はクライアントのコンソール ウィンドウに表示されます。0 による除算がエラーとして報告されたことが示されます。クライアントをシャットダウンするには、クライアント ウィンドウで Enter キーを押します。

Add(15,3) = 18
Subtract(145,76) = 69
Multiply(9,81) = 729
FaultException<MathFault>: Math fault while doing division. Problem: divide by zero

Press <ENTER> to terminate client.

クライアントでこれを行うには、適切な FaultException<MathFault> 例外を次のようにキャッチします。

catch (FaultException<MathFault> e)
{
    Console.WriteLine("FaultException<MathFault>: Math fault while doing " + e.Detail.operation + ". Problem: " + e.Detail.problemType);
    client.Abort();
}

既定では、サービス実装の詳細がサービスのセキュリティの境界から漏えいするのを回避するため、予期しない例外の詳細はクライアントに送信されません。FaultContract では、コントラクトでエラーを説明し、例外の特定の型がクライアントへの転送に適しているとマークできます。また FaultException<T> には、エラーをコンシューマに送信するためのランタイム機構が用意されています。

ただし、デバッグ時にはサービス エラーの内部詳細を確認することが役立ちます。前に説明したセキュリティ動作を無効にするには、サーバーで未処理のすべての例外の詳細を、クライアントに送信するエラーに含めるように指定できます。これは、IncludeExceptionDetailInFaultstrue に設定することによって行います。次の例に示すように、コードまたは構成のどちらを使用しても設定できます。

<behaviors>
  <serviceBehaviors>
    <behavior name="CalculatorServiceBehavior">
      <serviceMetadata httpGetEnabled="True"/>
      <serviceDebug includeExceptionDetailInFaults="True" />
    </behavior>
  </serviceBehaviors>
</behaviors>

さらに、サービスの behaviorConfiguration 属性を構成ファイルで “CalculatorServiceBehavior” に設定し、動作をサービスに関連付ける必要があります。

こうしたエラーをクライアントでキャッチするには、非ジェネリックの FaultException をキャッチする必要があります。

この動作はデバッグ目的でのみ使用し、製品版では有効にしないでください。

サンプルを設定、ビルド、および実行するには

  1. Windows Communication Foundation サンプルの 1 回限りのセットアップの手順」が実行済みであることを確認します。

  2. ソリューションの C# 版または Visual Basic .NET 版をビルドするには、「Windows Communication Foundation サンプルのビルド」の手順に従います。

  3. 単一コンピューター構成か複数コンピューター構成かに応じて、「Running the Windows Communication Foundation Samples」の手順に従います。

ms752208.Important(ja-jp,VS.100).gif 注 :
サンプルは、既にコンピューターにインストールされている場合があります。続行する前に、次の (既定の) ディレクトリを確認してください。

<InstallDrive>:\WF_WCF_Samples

このディレクトリが存在しない場合は、「.NET Framework 4 向けの Windows Communication Foundation (WCF) および Windows Workflow Foundation (WF) のサンプル」にアクセスして、Windows Communication Foundation (WCF) および WF のサンプルをすべてダウンロードしてください。このサンプルは、次のディレクトリに格納されます。

<InstallDrive>:\WF_WCF_Samples\WCF\Basic\Contract\Service\Faults