Определение и задание сбоев
Ошибки SOAP передают сведения об ошибке от службы клиенту и, в дуплексном случае, от клиента службе совместимым способом. В этом разделе описываются способы определения пользовательского содержимого ошибок и указываются операции, которые могут возвращать это содержимое. Дополнительные сведения том, как служба или дуплексный клиент могут отправлять такие ошибки и как клиентское приложение или приложение службы обрабатывает эти ошибки, см. в разделе Сбои при отправке и получении. Общие сведения об обработке ошибок в приложениях Windows Communication Foundation (WCF) см. в разделе Задание и обработка сбоев в контрактах и службах.
Общие сведения
Объявленные ошибки SOAP — это ошибки, в которых в операции имеется атрибут System.ServiceModel.FaultContractAttribute, указывающий пользовательский тип ошибки SOAP. Необъявленные ошибки SOAP — это ошибки, не указанные в контракте операции. Изучение этого раздела поможет определять такие состояния ошибки и создать для своей службы контракт ошибок, который может использоваться клиентами для правильной обработки состояния ошибки при уведомлении о пользовательской ошибке SOAP. Необходимо решить следующие основные задачи (порядок имеет значение):
Определить состояния ошибки, о которых должен знать клиент службы;
Определить пользовательское содержимое ошибок SOAP для этих состояний ошибки;
Отметить операции, чтобы создаваемые ими определенные ошибки 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(ByVal a As Integer, ByVal b As Integer) _
As Integer
If (b==0) Then
Throw New Exception("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 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
// 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; }
}
}
Дополнительные сведения том, как сделать данные сериализуемыми, см. раздел Задание передачи данных в контрактах служб. Список предусмотренных в System.Runtime.Serialization.DataContractSerializer способов поддержки сериализации см. в разделе Типы, поддерживаемые сериализатором контракта данных.
Разметка операций для установления контракта ошибок
После определения сериализуемой структуры данных, которая возвращается как часть пользовательской ошибки SOAP, нужно отметить контракт операции, как создающий ошибку SOAP этого типа. Для этого следует использовать атрибут System.ServiceModel.FaultContractAttribute и передать тип созданного пользовательского типа данных. В следующем примере кода показано, как с помощью атрибута FaultContractAttribute указать, что операция Divide
может возвращать ошибку SOAP типа MathFault
. Другие математические операции теперь тоже могут указывать, что могут вернуть ошибку MathFault
.
<OperationContract()> _
<FaultContract(GetType(MathFault))> _
Function Divide(ByVal n1 As Integer, ByVal n2 As Integer) As Integer
[OperationContract]
[FaultContract(typeof(MathFault))]
int Divide(int n1, int n2);
Операция может указывать, что возвращает несколько пользовательских ошибок, если она отмечена несколькими атрибутами FaultContractAttribute.
Следующий этап, реализация контракта ошибок в реализации операции, описан в разделе Сбои при отправке и получении.
Вопросы SOAP, WSDL и взаимодействия
В некоторых ситуациях, особенно при взаимодействиях с другими платформами, может быть важно контролировать представление ошибки в сообщении SOAP или способ ее описания в метаданных WSDL.
Атрибут FaultContractAttribute содержит свойство Name, позволяющее контролировать имя элемента ошибки WSDL, которое создается в метаданных этой ошибки.
В соответствии со стандартом SOAP для ошибки могут указываться атрибуты Action, Code и Reason. Action контролируется свойством Action. Свойства Code иReason — свойства класса System.ServiceModel.FaultException, родительского класса универсального класса System.ServiceModel.FaultException. Свойство Code включает член SubCode.
Существуют определенные ограничения при доступе к чему-либо, создающему ошибки и не являющемуся службой. WCF поддерживает только ошибки с типами сведений, описанными в схеме и совместимыми с контрактами данных. Например, как сказано выше, WCF не поддерживает ошибки, использующие в типах сведений атрибуты XML, а также ошибки, содержащие в разделе сведений более одного элемента верхнего уровня.
См. также
Задачи
Практическое руководство. Объявление сбоев в контрактах служб
Как устанавливать свойства ProtectionLevel
Справочник
FaultContractAttribute
DataContractAttribute
DataMemberAttribute
Основные понятия
Задание и обработка сбоев в контрактах и службах
Сбои при отправке и получении
Основные сведения об уровне защиты
Задание передачи данных в контрактах служб