Compartir vía


Contrato de responsabilidad

En el ejemplo de Fallos se muestra cómo comunicar información de error de un servicio a un cliente. El ejemplo se basa en Guía de inicio, con código adicional que se ha agregado al servicio para convertir una excepción interna en una falla. El cliente intenta realizar una división por cero para forzar una condición de error en el servicio.

Nota:

El procedimiento de instalación y las instrucciones de compilación de este ejemplo se encuentran al final de este tema.

El contrato de la calculadora se ha modificado para incluir un FaultContractAttribute, tal como se muestra en el siguiente código de ejemplo.

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

El FaultContractAttribute atributo indica que la Divide operación puede devolver un error de tipo MathFault. Un error puede ser de cualquier tipo que se pueda serializar. En este caso, es MathFault un contrato de datos, como se indica a continuación:

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

El Divide método produce una excepción cuando se produce una FaultException<TDetail> excepción de división por cero, como se muestra en el código de ejemplo siguiente. Esta excepción produce un error que se envía al 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);
    }
}

El código de cliente fuerza un error solicitando una división por cero. Al ejecutar el ejemplo, las solicitudes de operación y las respuestas se muestran en la ventana de la consola del cliente. Se puede ver la división por cero mientras se crea un informe con el error. Presione ENTRAR en la ventana del cliente para apagar el 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.

El cliente lo hace detectando la excepción adecuada FaultException<MathFault> :

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

De forma predeterminada, los detalles de excepciones inesperadas no se envían al cliente para evitar que los detalles de la implementación del servicio escapen al límite seguro del servicio. FaultContract proporciona una manera de describir los errores en un contrato y marcar determinados tipos de excepciones según corresponda para la transmisión al cliente. FaultException<T> proporciona el mecanismo en tiempo de ejecución para enviar errores a los consumidores.

Sin embargo, es útil para ver los detalles internos de un error del servicio al depurar. Para desactivar el comportamiento seguro descrito anteriormente, puede indicar que los detalles de cada excepción no controlada en el servidor deben incluirse en el error que se envía al cliente. Esto se logra configurando IncludeExceptionDetailInFaults a true. Puede establecerlo en el código o en la configuración, como se muestra en el ejemplo siguiente.

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

Además, el comportamiento debe estar asociado al servicio estableciendo el behaviorConfiguration atributo del servicio en el archivo de configuración en "CalculatorServiceBehavior".

Para detectar tales errores en el cliente, se debe detectar el FaultException no genérico.

Este comportamiento solo debe usarse con fines de depuración y nunca debe habilitarse en producción.

Para configurar, compilar y ejecutar el ejemplo

  1. Asegúrese de que ha realizado el procedimiento de instalación única para los ejemplos de Windows Communication Foundation.

  2. Para compilar el código C# o Visual Basic .NET Edition de la solución, siga las instrucciones de Building the Windows Communication Foundation Samples.

  3. Para ejecutar el ejemplo en una configuración de una máquina única o entre máquinas, siga las instrucciones de Ejecución de los ejemplos de Windows Communication Foundation.