Contrato de Falha

O exemplo de falhas demonstra como comunicar informações de erro de um serviço para um cliente. O exemplo é baseado na Introdução, com algum código adicional adicionado ao serviço para converter uma exceção interna em uma falha. O cliente tenta executar a divisão por zero para forçar uma condição de erro no serviço.

Nota

O procedimento de configuração e as instruções de compilação para este exemplo estão localizados no final deste tópico.

O contrato da calculadora foi modificado para incluir um, FaultContractAttribute conforme mostrado no código de exemplo a seguir.

[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);
}

O FaultContractAttribute atributo indica que a Divide operação pode retornar uma falha do tipo MathFault. Uma falha pode ser de qualquer tipo que possa ser serializada. Neste caso, trata-se de um contrato de dados, da MathFault seguinte forma:

[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; }
    }
}

O Divide método lança uma FaultException<TDetail> exceção quando ocorre uma exceção de divisão por zero, conforme mostrado no código de exemplo a seguir. Essa exceção resulta no envio de uma falha para o cliente.

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);
    }
}

O código do cliente força um erro solicitando uma divisão por zero. Quando você executa o exemplo, as solicitações de operação e as respostas são exibidas na janela do console do cliente. Você vê a divisão por zero sendo relatada como uma falha. Pressione ENTER na janela do cliente para desligar o cliente.

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.

O cliente faz isso pegando a exceção apropriada FaultException<MathFault> :

catch (FaultException<MathFault> e)
{
    Console.WriteLine("FaultException<MathFault>: Math fault while doing " + e.Detail.operation + ". Problem: " + e.Detail.problemType);
    client.Abort();
}

Por padrão, os detalhes de exceções inesperadas não são enviados ao cliente para evitar que os detalhes da implementação do serviço escapem do limite seguro do serviço. FaultContract fornece uma maneira de descrever falhas em um contrato e marcar certos tipos de exceções como apropriadas para transmissão ao cliente. FaultException<T> fornece o mecanismo de tempo de execução para enviar falhas aos consumidores.

No entanto, é útil ver os detalhes internos de uma falha de serviço durante a depuração. Para desativar o comportamento seguro descrito anteriormente, você pode indicar que os detalhes de cada exceção não tratada no servidor devem ser incluídos na falha enviada ao cliente. Isso é feito definindo IncludeExceptionDetailInFaults como true. Você pode defini-lo em código ou em configuração, conforme mostrado no exemplo a seguir.

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

Além disso, o comportamento deve ser associado ao serviço definindo o behaviorConfiguration atributo do serviço no arquivo de configuração como "CalculatorServiceBehavior".

Para detetar tais falhas no cliente, o não genérico FaultException deve ser capturado.

Esse comportamento só deve ser usado para fins de depuração e nunca deve ser habilitado na produção.

Para configurar, compilar e executar o exemplo

  1. Certifique-se de ter executado o procedimento de instalação única para os exemplos do Windows Communication Foundation.

  2. Para criar a edição C# ou Visual Basic .NET da solução, siga as instruções em Criando os exemplos do Windows Communication Foundation.

  3. Para executar o exemplo em uma configuração de máquina única ou cruzada, siga as instruções em Executando os exemplos do Windows Communication Foundation.