次の方法で共有


障害コントラクト

Faults サンプルは、サービスからクライアントにエラー情報を伝達する方法を示しています。 このサンプルは作業 の開始に基づいており、内部例外をエラーに変換するためのコードがサービスに追加されています。 クライアントは 0 による除算を実行して、サービスでエラー状態を強制しようとします。

このサンプルのセットアップ手順とビルド手順は、このトピックの最後にあります。

電卓コントラクトは、次のサンプル コードに示すように、 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; }
    }
}

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

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

クライアント コードは、ゼロ除算を要求してエラーを強制します。 サンプルを実行すると、操作要求と応答がクライアント コンソール ウィンドウに表示されます。 ゼロによる除算がエラーとして報告されていることがわかります。 クライアント ウィンドウで 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 サンプル One-Time セットアップ手順を実行していることを確認します。

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

  3. 単一または複数のコンピューター間の構成でサンプルを実行するには、「Windows Communication Foundation Samplesの実行」の手順に従います。