Поделиться через


Контракт ошибок

Этот образец демонстрирует передачу информации об ошибке из службы клиенту. Этот образец основан на образце Образец для начала работы с добавлением в службу некоторого кода для преобразования внутреннего исключения в сбой. Клиент пытается выполнить операцию деления на ноль для принудительного сбоя службы.

ms752208.note(ru-ru,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; }
    }
}

Метод 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);
    }
}

Клиентский код принудительно создает ошибку, запрашивая деление не ноль. При выполнении образца запросы и ответы операций отображаются в окне консоли клиента. Деление на ноль будет выведено на консоль в виде сбоя. Чтобы закрыть клиент, нажмите клавишу ВВОД в окне клиента.

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> предоставляет механизм времени выполнения для отправки сбоев потребителям.

Тем не менее, при отладке удобно иметь возможность просматривать внутренние сведения о сбое службы. Для отключения описанного выше защитного поведения можно указать, что сведения о каждом необработанном исключении на сервере должны включаться в отправляемый клиенту сбой. Это делается путем присвоения свойству IncludeExceptionDetailInFaults значения true. Задать это свойство можно в коде или в конфигурации, как показано в следующем образце.

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

Кроме того, поведение должно быть связано со службой путем присвоения атрибуту behaviorConfiguration службы в файле конфигурации значения "CalculatorServiceBehavior".

Для перехвата таких сбоев на клиенте необходимо перехватывать неуниверсальное исключение FaultException.

Это поведение следует использовать только в целях отладки и ни в коем случае не в рабочей среде.

Настройка, построение и выполнение образца

  1. Убедитесь, что выполнены процедуры, описанные в разделе Процедура однократной настройки образцов Windows Communication Foundation.

  2. Чтобы выполнить построение версии решения для языка C# или Visual Basic .NET, следуйте инструкциям раздела Построение образцов Windows Communication Foundation.

  3. Чтобы выполнить образец на одном или нескольких компьютерах, следуйте инструкциям в разделе Running the Windows Communication Foundation Samples.

ms752208.Important(ru-ru,VS.100).gif Примечание
Образцы уже могут быть установлены на компьютере. Перед продолжением проверьте следующий каталог (по умолчанию).

<диск_установки>:\WF_WCF_Samples

Если этот каталог не существует, перейдите на страницу Образцы Windows Communication Foundation (WCF) и Windows Workflow Foundation (WF) для .NET Framework 4, чтобы загрузить все образцы Windows Communication Foundation (WCF) и WF. Этот образец расположен в следующем каталоге.

<диск_установки>:\WF_WCF_Samples\WCF\Basic\Contract\Service\Faults