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


Определение и задание сбоев

Ошибки SOAP передают сведения об ошибке от службы клиенту и, в дуплексном случае, от клиента службе совместимым способом. В этом разделе описано, как и когда можно определить содержимое пользовательских ошибок и задать операции, которые могут возвратить это содержимое. Дополнительные сведения о том, как служба или дуплексный клиент могут отправлять эти ошибки и как клиент или приложение службы обрабатывает эти ошибки, см. в статье "Отправка и получение сбоев". Общие сведения об обработке ошибок в приложениях Windows Communication Foundation (WCF) см. в разделе "Указание и обработка ошибок в контрактах и службах".

Обзор

Объявленные ошибки SOAP - это ошибки, в которых в операции имеется атрибут System.ServiceModel.FaultContractAttribute, указывающий пользовательский тип ошибки SOAP. Необъявленные ошибки SOAP - это ошибки, не указанные в контракте операции. Изучение этого раздела поможет определять такие состояния ошибки и создать для своей службы контракт ошибок, который может использоваться клиентами для правильной обработки состояния ошибки при уведомлении о пользовательской ошибке SOAP. Необходимо решить следующие основные задачи (порядок имеет значение):

  1. Определить состояния ошибки, о которых должен знать клиент службы;

  2. Определить пользовательское содержимое ошибок SOAP для этих состояний ошибки;

  3. Отметить операции, чтобы создаваемые ими определенные ошибки SOAP предоставлялись клиентам в формате WSDL.

Определение состояний ошибки, о которых должен знать клиент

Ошибки SOAP - это общедоступные сообщения, содержащие сведения об ошибке определенной операции. Так как они описаны вместе с другими сообщениями операций в WSDL, клиенты знают о них и, следовательно, готовы обрабатывать такие ошибки при вызове операции. Но поскольку службы WCF записываются в управляемый код, решая, какие условия ошибки в управляемом коде необходимо преобразовать в ошибки и вернуть клиенту, предоставляет возможность разделить условия ошибок и ошибки в службе от официального диалога об ошибках, которые у вас есть с клиентом.

Например, в следующем примере кода показана операция, которая принимает два целых числа и возвращает другое целое число. Здесь может быть создано несколько исключений, поэтому при разработке контракта ошибок нужно определить, какие состояния ошибки важны для клиента. В этом случае служба должна обнаруживать исключение System.DivideByZeroException.

[ServiceContract]  
public class CalculatorService  
{  
    [OperationContract]
    int Divide(int a, int b)  
    {  
      if (b==0) throw new Exception("Division by zero!");  
      return a/b;  
    }  
}  
<ServiceContract> _
Public Class CalculatorService
    <OperationContract> _
    Public Function Divide(a As Integer, b As Integer) As Integer
        If b = 0 Then Throw New DivideByZeroException("Division by zero!")
        Return a / b
    End Function
End Class

В данном примере операция может вернуть пользовательскую ошибку SOAP о делении на ноль, пользовательскую ошибку, связанную с математическими операциями, но содержащую сведения о делении на ноль, несколько ошибок для различных ситуаций с ошибками или не возвращать ошибок SOAP.

Определение содержимого состояний ошибки

Если установлено, что состояние ошибки может вернуть полезную пользовательскую ошибку SOAP, необходимо определить содержимое этой ошибки и убедиться, что структура содержимого сериализуется. В примере кода в предыдущем разделе показана ошибка, связанную с операцией Divide, но если в службе Calculator содержатся другие операции, одна пользовательская ошибка SOAP может сообщать клиенту обо всех состояниях ошибки калькулятора, включая Divide. В следующем коде показан пример создания пользовательской ошибки SOAP, MathFault, которая может сообщать об ошибках, произошедших при любых математических операциях, включая Divide. Класс может задавать операцию (свойство Operation) и значение, описывающее проблему (свойство ProblemType), но при этом класс и эти свойства должны быть сериализуемы, чтобы их можно было передать клиенту в пользовательской ошибке SOAP. Чтобы обеспечить максимальный уровень сериализуемости типа и его свойств, а также максимальный уровень взаимодействия, используются атрибуты System.Runtime.Serialization.DataContractAttribute и System.Runtime.Serialization.DataMemberAttribute.

// Define a math fault data contract
[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; }
    }
}
' Define a math fault data contract
<DataContract([Namespace]:="http://Microsoft.ServiceModel.Samples")> _
Public Class MathFault

    Private m_operation As String
    Private m_problemType As String

    <DataMember()> _
    Public Property Operation() As String

        Get

            Return m_operation

        End Get

        Set(ByVal value As String)

            m_operation = value

        End Set

    End Property

    <DataMember()> _
    Public Property ProblemType() As String

        Get

            Return m_problemType

        End Get

        Set(ByVal value As String)

            m_problemType = value

        End Set

    End Property

End Class

Дополнительные сведения о том, как убедиться, что данные сериализуются, см. в разделе "Указание передачи данных в контрактах служб". Список поддержки сериализации, которая System.Runtime.Serialization.DataContractSerializer предоставляет, см. в разделе "Типы, поддерживаемые сериализатором контракта данных".

Разметка операций для установления контракта ошибок

После определения сериализуемой структуры данных, которая возвращается как часть пользовательской ошибки SOAP, нужно отметить контракт операции, как создающий ошибку SOAP этого типа. Для этого следует использовать атрибут System.ServiceModel.FaultContractAttribute и передать тип созданного пользовательского типа данных. В следующем примере кода показано, как с помощью атрибута FaultContractAttribute указать, что операция Divide может возвращать ошибку SOAP типа MathFault. Другие математические операции теперь тоже могут указывать, что могут вернуть ошибку MathFault.

[OperationContract]
[FaultContract(typeof(MathFault))]
int Divide(int n1, int n2);
<OperationContract()> _
<FaultContract(GetType(MathFault))> _
Function Divide(ByVal n1 As Integer, ByVal n2 As Integer) As Integer

Операция может указывать, что возвращает несколько пользовательских ошибок, если она отмечена несколькими атрибутами FaultContractAttribute.

Следующий шаг, чтобы реализовать контракт сбоя в реализации операции, описан в разделе "Отправка и получение сбоев".

Вопросы SOAP, WSDL и взаимодействия

В некоторых ситуациях, особенно при взаимодействиях с другими платформами, может быть важно контролировать представление ошибки в сообщении SOAP или способ ее описания в метаданных WSDL.

Атрибут FaultContractAttribute содержит свойство Name, позволяющее контролировать имя элемента ошибки WSDL, которое создается в метаданных этой ошибки.

В соответствии со стандартом SOAP для ошибки могут указываться атрибуты Action, Code и Reason. Action контролируется свойством Action. Свойства Code иReason - свойства класса System.ServiceModel.FaultException, родительского класса универсального класса System.ServiceModel.FaultException<TDetail>. Свойство Code включает член SubCode.

Существуют некоторые ограничения доступа к службам, создающим ошибки. WCF поддерживает только ошибки с типами подробностей, описывающими схему и совместимыми с контрактами данных. Например, как упоминание выше, WCF не поддерживает ошибки, использующие XML-атрибуты в их типах подробностей, или ошибки с несколькими элементами верхнего уровня в разделе сведений.

См. также