Manejando excepciones en WCF

Una de las cosas con las que me he encontrado mas agradables en WCF es el manejo de excepciones. Alguien recuerda como las teniamos que hacer para enviar una excepcion a traves de un servicio Web?? Bastante lioso o al menos para mi.

En cambio en WCF es bastante sencillo realizarlo, lo primero que vamso a ver es returnUnknownExceptionsAsFaults.

WCF nos ofrece una opción para lanzar automaticamente cualquier exceeción que se produzca en nuestro sercicio como una Soap Fault. Para habilitarlo debemos de introducir returnUnknownExceptionsAsFaults = ‘True’ en el behaivor del servicio en el fichero de configuración

<behaviors> 
<behavior name="OrderingServiceBehavior" 
returnUnknownExceptionsAsFaults="True"> 
</behavior> 
</behaviors>

De manera que cuando se produzca cualquier excepción nos mandara una UnknownFaultException. Realmente lo que nos enviara sera toda la información del error producido que esta muy bien cuando desarrollamos pero por favor en producción nunca,nunca nunca habiliteis esta opción porque en cuanto se produzca una excepción en vuestro servicio el cliente puede recibir informacion que nosotros no desaemos que tenga.

FaultContract

Nos va a permitir crear nuestras propias clases de excepciones con la información que nosotros queremos transmitir al cliente. Vamos a ver como la utilizamos en los siguientes pasos.

Primero creamos nuestra clase de excepción como si fuese un DataContract de nuestro servicio

 [DataContract]
    public class SomeError
    {
        [DataMember]
        public string Content;
    }

Lo siguiente es en el Interfaz del servicio en el metodo que queremos controlar la excepción, debemos introducir el atributo Faultcontract

 

[OperationContract(Name = "Error")]
[FaultContract(typeof(SomeError))]
decimal DividebyZero(decimal input);

Al introducir este atributo en esta operación, se esta informando a los clientes que el servicio puede retornar un mensaje de error que esta definido en el DataContract SomeError.

 Implementamos el metodo de la interfaz

 public decimal DividebyZero(decimal input)
        {
            try
            {
                decimal denominator=0;
                return input / denominator;

            }
            catch (Exception exception)
            {

                SomeError error = new SomeError();
                error.Content = exception.Message;
                throw new FaultException<SomeError>(error);
            }
        }

Vemos que el codigo introducido es el mismo que si no estuviesemos utilizando Indigo excepto que en el control de la excepción estoy relanzando una FaultException del tipo SomeError.

El cliente deberia tratarlo de la siguiente manera

try
    {
       proxy.DividebyZero(0);
    }
 catch (FaultException<SomeError> exception)
   {

        Console.WriteLine("Error : {0}", exception.Detail.Content);
    }

 

 Facil de gestionar !!!

2 comentarios sobre “Manejando excepciones en WCF”

  1. Ojo!!! Lo que comentaba Oskar, ha cambiado un poco. Ya no se usa returnUnknownExceptionsAsFaults sino includeExceptionDetailInFaults.

    http://wcf.netfx3.com/content/BreakingChangesbetweenVistaBeta2andJuneCTP.aspx

    Configuration of behaviors has changed:

    Behaviors are now scoped by service or by endpoint under system.serviceModel/behaviors/serviceBehaviors and system.serviceModel/behaviors/endpointBehaviors respectively. Further, the system.serviceModel/behaviors/behavior/@returnUnknownExceptionsAsFaults has been replaced with system.serviceModel/behaviors/serviceBehaviors/serviceDebug/@includeExceptionDetailInFaults. This attribute controls whether exception detail is included in a fault that occurs when a service encounters an unhandled exception.

    Before





    After













  2. Hay algo que quiero añadir, es un comportamiento que he detectado. Si hay una excepción interna que no se atrapa y se define como FaultException exception, entonces el canal se cerrará, así que para evitar que el canal se cierre, siempre se deben definir las excepciones como FaultException exception (para este caso de ejemplo) en todos los niveles (capas) del código, si se así así entonces el canal no se cierra porque se está devolviendo una excepción tal como dice el contrato.

    Saludos.

Responder a rcorral Cancelar respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *