Контракт ошибок
В примере "Ошибки" показано, как передавать сведения об ошибках из службы клиенту. Пример основан на начале работы с дополнительным кодом, добавленным в службу для преобразования внутреннего исключения в ошибку. Клиент пытается выполнить операцию деления на ноль для принудительного сбоя службы.
Примечание.
Процедура настройки и инструкции по построению для данного образца приведены в конце этого раздела.
В контракт калькулятора добавлен атрибут 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<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);
}
}
Клиентский код принудительно создает ошибку, запрашивая деление не ноль. При выполнении примера запросы и ответы операций отображаются в окне консоли клиента. Деление на ноль будет выведено на консоль в виде сбоя. Чтобы закрыть клиент, нажмите клавишу ВВОД в окне клиента.
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.
Это поведение следует использовать только в целях отладки и ни в коем случае не в рабочей среде.
Настройка, сборка и выполнение образца
Убедитесь, что вы выполнили процедуру однократной установки для примеров Windows Communication Foundation.
Чтобы создать выпуск решения на языке C# или Visual Basic .NET, следуйте инструкциям в разделе Building the Windows Communication Foundation Samples.
Чтобы запустить пример в конфигурации с одним или несколькими компьютерами, следуйте инструкциям в разделе "Примеры Windows Communication Foundation".