Compartilhar via


Definindo e especificando falhas

As falhas SOAP transmitem informações de condição de erro de um serviço para um cliente e, no caso duplex, de um cliente para um serviço de forma interoperável. Este tópico discute quando e como definir conteúdo de falha personalizado e especificar quais operações podem devolvê-los. Para obter mais informações sobre como um serviço ou cliente duplex pode enviar essas falhas e como um cliente ou aplicativo de serviço lida com essas falhas, consulte Envio e Recebimento de Falhas. Para obter uma visão geral do tratamento de erros em aplicativos do WCF (Windows Communication Foundation), consulte Especificando e tratando falhas em contratos e serviços.

Visão geral

Falhas SOAP declaradas são aquelas em que uma operação possui um System.ServiceModel.FaultContractAttribute que especifica um tipo personalizado de falha SOAP. Falhas SOAP não declaradas são aquelas que não são especificadas no contrato para uma operação. Este tópico ajuda você a identificar essas condições de erro e criar um contrato de falha para seu serviço que os clientes podem usar para lidar corretamente com essas condições de erro quando notificados por falhas soap personalizadas. As tarefas básicas são, em ordem:

  1. Defina as condições de erro sobre as quais um cliente do serviço deve saber.

  2. Defina o conteúdo personalizado das falhas SOAP para essas condições de erro.

  3. Marque suas operações para que as falhas SOAP específicas que elas lançam sejam expostas a clientes no WSDL.

Definindo condições de erro sobre as quais os clientes devem saber

As falhas SOAP são mensagens descritas publicamente que carregam informações de erro para uma operação específica. Como elas são descritas junto com outras mensagens de operação no WSDL, os clientes sabem e, portanto, esperam lidar com essas falhas ao invocar uma operação. No entanto, como os serviços WCF são escritos em código gerenciado, decidir quais condições de erro no código gerenciado devem ser convertidas em falhas e retornados ao cliente oferece a oportunidade de separar condições de erro e bugs em seu serviço da conversa de erro formal que você tem com um cliente.

Por exemplo, o exemplo de código a seguir mostra uma operação que usa dois inteiros e retorna outro inteiro. Várias exceções podem ser geradas aqui, portanto, ao projetar o contrato de falha, você deve determinar quais condições de erro são importantes para o cliente. Nesse caso, o serviço deve detectar a System.DivideByZeroException exceção.

[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

No exemplo anterior, a operação pode retornar uma falha SOAP personalizada específica à divisão por zero, uma falha personalizada específica para operações matemáticas, mas que contém informações específicas de divisão por zero, várias falhas para várias situações de erro diferentes ou nenhuma falha SOAP.

Definir o conteúdo das condições de erro

Depois que uma condição de erro tiver sido identificada como uma que possa retornar útilmente uma falha SOAP personalizada, a próxima etapa é definir o conteúdo dessa falha e garantir que a estrutura de conteúdo possa ser serializada. O exemplo de código na seção anterior mostra um erro específico a uma Divide operação, mas se houver outras operações no Calculator serviço, uma única falha SOAP personalizada poderá informar o cliente sobre todas as condições de erro da calculadora, incluindo Divide. O exemplo de código a seguir mostra a criação de uma falha SOAP personalizada, MathFaultque pode relatar erros feitos usando todas as operações matemáticas, incluindo Divide. Embora a classe possa especificar uma operação (a Operation propriedade) e um valor que descreva o problema (a ProblemType propriedade), a classe e essas propriedades devem ser serializáveis para serem transferidas para o cliente em uma falha SOAP personalizada. Portanto, os atributos System.Runtime.Serialization.DataContractAttribute e System.Runtime.Serialization.DataMemberAttribute são usados para tornar o tipo e suas propriedades serializáveis e o mais interoperáveis possível.

// 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

Para obter mais informações sobre como garantir que seus dados sejam serializáveis, consulte Especificando a transferência de dados em contratos de serviço. Para obter uma lista do suporte à serialização que System.Runtime.Serialization.DataContractSerializer fornece, consulte Tipos compatíveis com o Serializador de Contrato de Dados.

Definir operações para estabelecer o contrato de responsabilidade por falhas

Após a definição da estrutura de dados serializável retornada como parte de uma falha SOAP personalizada, a última etapa é marcar seu contrato de operação como gerando uma falha de SOAP desse tipo. Para fazer isso, use o System.ServiceModel.FaultContractAttribute atributo e passe o tipo do tipo de dados personalizado que você construiu. O exemplo de código a seguir mostra como usar o FaultContractAttribute atributo para especificar que a Divide operação pode retornar uma falha SOAP do tipo MathFault. Outras operações baseadas em matemática agora também podem especificar que podem retornar uma 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

Uma operação pode especificar que ela retorna mais de uma falha personalizada marcando essa operação com mais de um FaultContractAttribute atributo.

A próxima etapa, para implementar o contrato de falha na implementação da operação, é descrita no tópico Envio e Recebimento de Falhas.

Considerações sobre SOAP, WSDL e Interoperabilidade

Em algumas circunstâncias, especialmente ao interoperar com outras plataformas, pode ser importante controlar a maneira como uma falha aparece em uma mensagem SOAP ou a maneira como ela é descrita nos metadados do WSDL.

O FaultContractAttribute atributo tem uma Name propriedade que permite o controle do nome do elemento de falha WSDL que é gerado nos metadados para essa falha.

De acordo com o padrão SOAP, uma falha pode ter um Action, um Codee um Reason. O Action é controlado pela Action propriedade. A propriedade Code e a propriedade Reason são ambas propriedades da classe System.ServiceModel.FaultException, que é a classe pai da classe genérica System.ServiceModel.FaultException<TDetail>. A Code propriedade inclui um SubCode membro.

Ao acessar não-serviços que geram falhas, existem determinadas limitações. O WCF dá suporte apenas a falhas com tipos de detalhes que o esquema descreve e que são compatíveis com contratos de dados. Por exemplo, conforme mencionado acima, o WCF não dá suporte a falhas que usam atributos XML em seus tipos de detalhes ou falhas com mais de um elemento de nível superior na seção de detalhes.

Consulte também