Kontrak Kesalahan

Sampel Kesalahan menunjukkan cara mengomunikasikan informasi kesalahan dari layanan ke klien. Sampel didasarkan pada Memulai, dengan beberapa kode tambahan ditambahkan ke layanan untuk mengonversi pengecualian internal menjadi kesalahan. Klien mencoba melakukan pembagian dengan nol untuk menyebabkan kondisi kesalahan pada sistem layanan.

Nota

Prosedur penyiapan dan instruksi build untuk sampel ini terletak di akhir topik ini.

Kontrak kalkulator telah dimodifikasi untuk menyertakan sebuah FaultContractAttribute seperti yang ditunjukkan dalam kode sampel berikut.

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

Atribut FaultContractAttribute menunjukkan bahwa Divide operasi dapat mengembalikan kesalahan jenis MathFault. Kesalahan bisa dari jenis apa pun yang dapat diserialisasikan. Dalam hal ini, MathFault adalah kontrak data, sebagai berikut:

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

Metode ini Divide melempar FaultException<TDetail> pengecualian ketika pengecualian pembagian dengan nol terjadi, seperti yang ditunjukkan dalam contoh kode berikut. Pengecualian ini menyebabkan kesalahan dikirim ke klien.

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

Kode klien memaksa kesalahan dengan meminta pembagian dengan nol. Saat Anda menjalankan sampel, permintaan dan respons operasi ditampilkan di jendela konsol klien. Anda melihat pembagian dengan nol dilaporkan sebagai kesalahan. Tekan ENTER di jendela klien untuk mematikan klien.

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.

Klien melakukan ini dengan menangkap pengecualian yang sesuai: FaultException<MathFault>

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

Secara default, detail pengecualian tak terduga tidak dikirim ke klien untuk mencegah detail implementasi layanan melarikan diri dari batas layanan yang aman. FaultContract menyediakan cara untuk menjelaskan kesalahan dalam kontrak dan menandai jenis pengecualian tertentu yang sesuai untuk transmisi ke klien. FaultException<T> menyediakan mekanisme runtime untuk mengirim kesalahan kepada konsumen.

Namun, berguna untuk melihat detail internal kegagalan layanan saat melakukan debugging. Untuk menonaktifkan perilaku aman yang dijelaskan sebelumnya, Anda dapat menunjukkan bahwa detail setiap pengecualian yang tidak tertangani di server harus disertakan dalam kesalahan yang dikirim ke klien. Ini dicapai dengan mengatur IncludeExceptionDetailInFaults ke true. Anda dapat mengaturnya dalam kode, atau dalam konfigurasi seperti yang ditunjukkan dalam sampel berikut.

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

Selanjutnya, perilaku harus dikaitkan dengan layanan dengan mengatur behaviorConfiguration atribut layanan dalam file konfigurasi ke "CalculatorServiceBehavior".

Untuk menangkap kesalahan seperti itu pada klien, FaultException yang non-generik harus ditangkap.

Perilaku ini hanya boleh digunakan untuk tujuan penelusuran kesalahan dan tidak boleh diaktifkan dalam produksi.

Untuk menyiapkan, mengompilasi, dan menjalankan sampel

  1. Pastikan Anda telah melakukan Prosedur Penyiapan One-Time untuk Sampel Windows Communication Foundation.

  2. Untuk membangun solusi edisi C# atau Visual Basic .NET, ikuti instruksi di Membangun Sampel Windows Communication Foundation.

  3. Untuk menjalankan sampel dalam konfigurasi satu atau lintas komputer, ikuti instruksi di Menjalankan Sampel Windows Communication Foundation.