none
Cual es la diferencia entre Faults y Exception RRS feed

  • Pregunta

  • Hola a todos espero que esten bien...

    Cuales son las diferencias entre Faults y Exception y cuando deberia usar una u otra?

    De acuerdo a lo leido en varias paginas es algo asi:

    Exception se refieren como mecanismos usados para comunicar problemas encontrados cuando un programa se ejecuta.

    Faults son referidas  a mecanismos de falla SOAP previendo una estructura para el contenido del cuerpo del mensaje cuando un error ocurre.

    Pero la verdad me parece casi lo mismo, incluso he visto varios ejemplo y hasta hay una clase llamada FaultException http://msdn.microsoft.com/en-us/library/ms576199.aspx y en mi ignorancia es simplemente una Excepcion...

    Gracias de antemano a todos por su ayuda

    miércoles, 11 de abril de 2012 7:19

Respuestas

  • Hola,

    Creo que estás haciendo últimamente preguntas muy interesantes. Su respuesta debería ser conocida por todo aquel que quiera ser un gran programador de WCF... :)

    Cuando desarrollas un servicio usando WCF y dentro de un método lanzas una excepción, esta se envía al cliente en forma de FaultException<ExceptionDetail> (en antiguas versiones de la framework .Net creo recordar que era en forma de SoapException). Por ejemplo, partiendo de este servicio:

    public interface IMyService
    {
       [OperationContract]
       void DoWork(int i);
    }
    
    public class MyService : IMyService
    {
       public void DoWork(int i)
       {
          if (i == 0)
             throw new NotImplementedException("Zero is not implemented yet.");
          else if (i == 1)
             throw new ArgumentException("Cannot be one.")
       }
    }

    Creamos un cliente que lo llame:

    public void CallDoWork(int i)
    {
       using (var factory = new ChannelFactory<IMyService>("MyServiceEndPointName"))
       {
          var proxy = factory.CreateChannel();
          proxy.DoWork(i);
       }
    }

    Obtendremos una excepción de tipo "FaultException<ExceptionDetail>", siempre que le enviemos el valor '1' o '0'. Pero aunque la excepción sea diferente el servicio no diferencia a la hora de enviarla. Para poder diferenciar el tipo de excepción lo primero que tendremos que hacer es crear objetos transportables (Data Transfer Objects) que puedan transportar la información de la excepción. Y lo segundo 'avisar' al servicio de que va a devolver ese tipo de errores.

    En el ejemplo anterior si quisieramos diferenciar "ArgumentException" del resto de excepciones que se produzcan, crearíamos un objeto DTO para transportar el mensaje de error:

    [DataContract]
    public class ArgumentFault
    {
       [DataMember]
       public string Message {get;set;}
    }

    Después modificaríamos nuestro servicio para que enviara este nuevo tipo de falta:

    public void DoWork(int i)
    {
       if (i == 0)
       {
          throw new NotImplementedException("Zero is not implemented yet.");
       }
       else if (i == 1)
       {
          var fault = new ArgumentFault { Message = "Cannot be one." };
          throw new FaultException<ArgumentFault >(fault);
       }
    }

    Le indicaríamos al contrato de nuestro servicio que envía este tipo de "falta":

    public interface IMyService
    {
       [OperationContract]
       [FaultContract(typeof(ArgumentFault))]
       void DoWork(int i);
    }


    Y ahora en el cliente podríamos ser capaces de diferenciar esta "excepción" o "falta", del resto:

    public void CallDoWork(int i)
    {
       using (var factory = new ChannelFactory<IMyService>("MyServiceEndPointName"))
       {
          var proxy = factory.CreateChannel();
          try
          {
             proxy.DoWork(i);
          }
          catch(FaultException<ArgumentFault> argEx)
          {
             // Le he enviado parámetro 1
          }
          catch(Exception ex)
          {
             // otra falta cualquiera
          }
       }
    }

    Cuando le pase valor cero u ocurra cualquier otra excepción no controlada, el servicio me seguirá devolviendo un tipo FaultException<ExceptionDetail>. Pero cuando tenga la excepción por culpa del valor 1, podré diferenciarla.

    Un saludo,


    Fernanando Escolar - http://www.programandonet.com/ - @fernandoescolar

    • Marcado como respuesta AdyIr jueves, 12 de abril de 2012 4:03
    miércoles, 11 de abril de 2012 9:16

Todas las respuestas

  • Hola,

    Creo que estás haciendo últimamente preguntas muy interesantes. Su respuesta debería ser conocida por todo aquel que quiera ser un gran programador de WCF... :)

    Cuando desarrollas un servicio usando WCF y dentro de un método lanzas una excepción, esta se envía al cliente en forma de FaultException<ExceptionDetail> (en antiguas versiones de la framework .Net creo recordar que era en forma de SoapException). Por ejemplo, partiendo de este servicio:

    public interface IMyService
    {
       [OperationContract]
       void DoWork(int i);
    }
    
    public class MyService : IMyService
    {
       public void DoWork(int i)
       {
          if (i == 0)
             throw new NotImplementedException("Zero is not implemented yet.");
          else if (i == 1)
             throw new ArgumentException("Cannot be one.")
       }
    }

    Creamos un cliente que lo llame:

    public void CallDoWork(int i)
    {
       using (var factory = new ChannelFactory<IMyService>("MyServiceEndPointName"))
       {
          var proxy = factory.CreateChannel();
          proxy.DoWork(i);
       }
    }

    Obtendremos una excepción de tipo "FaultException<ExceptionDetail>", siempre que le enviemos el valor '1' o '0'. Pero aunque la excepción sea diferente el servicio no diferencia a la hora de enviarla. Para poder diferenciar el tipo de excepción lo primero que tendremos que hacer es crear objetos transportables (Data Transfer Objects) que puedan transportar la información de la excepción. Y lo segundo 'avisar' al servicio de que va a devolver ese tipo de errores.

    En el ejemplo anterior si quisieramos diferenciar "ArgumentException" del resto de excepciones que se produzcan, crearíamos un objeto DTO para transportar el mensaje de error:

    [DataContract]
    public class ArgumentFault
    {
       [DataMember]
       public string Message {get;set;}
    }

    Después modificaríamos nuestro servicio para que enviara este nuevo tipo de falta:

    public void DoWork(int i)
    {
       if (i == 0)
       {
          throw new NotImplementedException("Zero is not implemented yet.");
       }
       else if (i == 1)
       {
          var fault = new ArgumentFault { Message = "Cannot be one." };
          throw new FaultException<ArgumentFault >(fault);
       }
    }

    Le indicaríamos al contrato de nuestro servicio que envía este tipo de "falta":

    public interface IMyService
    {
       [OperationContract]
       [FaultContract(typeof(ArgumentFault))]
       void DoWork(int i);
    }


    Y ahora en el cliente podríamos ser capaces de diferenciar esta "excepción" o "falta", del resto:

    public void CallDoWork(int i)
    {
       using (var factory = new ChannelFactory<IMyService>("MyServiceEndPointName"))
       {
          var proxy = factory.CreateChannel();
          try
          {
             proxy.DoWork(i);
          }
          catch(FaultException<ArgumentFault> argEx)
          {
             // Le he enviado parámetro 1
          }
          catch(Exception ex)
          {
             // otra falta cualquiera
          }
       }
    }

    Cuando le pase valor cero u ocurra cualquier otra excepción no controlada, el servicio me seguirá devolviendo un tipo FaultException<ExceptionDetail>. Pero cuando tenga la excepción por culpa del valor 1, podré diferenciarla.

    Un saludo,


    Fernanando Escolar - http://www.programandonet.com/ - @fernandoescolar

    • Marcado como respuesta AdyIr jueves, 12 de abril de 2012 4:03
    miércoles, 11 de abril de 2012 9:16
  • Hola Fernando

    Muchas gracias en verdad y bueno disculpa la preguntardera, pero es que me estoy leyendo el libro de certificación de WCF y hay cosas que no entiendo... Y bueno al igual que los otros hilos en  verdad muchisimass gracias en verdad mucha mas claro que el libro y msdn...

    Todo quedo claro, saludos!!!

    jueves, 12 de abril de 2012 3:15