2009-10-08 13 views
23

Tengo un servicio WCF implementado en dos o más máquinas remotas y hay una aplicación de escritorio que utiliza el cliente para acceder a cualquier servicio wcf.¿Cuál es el mejor enfoque para manejar excepciones en el servicio WCF?

El servicio WCF está conectado a SQL Server 2005 para leer y escribir datos. Este es un escenario de intranet en el cual el cliente debe estar en el mismo dominio.

Ahora no puede haber situaciones donde el servicio WCF lanza excepciones:

  1. URL no válida
  2. servicio
  3. WCF está abajo
  4. SQL Server 2005 no se está ejecutando
  5. cliente no está en el mismo dominio
  6. autenticación falla
  7. autorización falla

y muchas otras excepciones.

Para cada excepción, tengo que realizar alguna acción o actualizar una barra de estado, dependiendo de la excepción. Por ejemplo, si la autorización falla, tengo que pedirle al usuario que vuelva a ingresar sus credenciales.

Por favor, sugiera el mejor enfoque de diseño para manejar esto.

Respuesta

32

Puede definitivamente capturar y manejar todas las excepciones que se producen en su clase de servicio y convertirlas en una excepción FaultException o FaultException.

De esta forma, no "fallará" (ni destruirá) el canal de comunicaciones entre su cliente y su servidor.

Un enfoque aún mejor sería implementar la interfaz IErrorHandler en su clase de servicio que proporciona una forma de detectar globalmente todas las excepciones a medida que ocurren y proporcionar una FaultException, que es compatible con SOAP.

Incluso puede convertir su IErrorHandler en un comportamiento configurable que se puede activar o desactivar en la configuración.

Consulte estos artículos y entradas de blog para más detalles:

+1

No sé mucho sobre IErrorHandler pero he leído artículos y publicaciones sobre el uso de IErrorHandler dice que tiene algunas desventajas. En algunos casos, la excepción puede ser lanzada directamente desde el servicio wcf al cliente. ¿Me recomendarías para IErrorHandler? –

+0

Sí, por supuesto, ** siempre ** recomendaría usar IErrorHandler. ¿Puedes publicar los enlaces a estos artículos que dicen que tiene desventajas? Nunca he oído hablar de ellos; me gustaría investigar ... –

+0

http://stackoverflow.com/questions/265551/wcf-errorhandler ¡Lee la segunda publicación! No sé si es correcto o no, pero siempre crea la confusión en mi mente –

2

Puede diseñar los Contratos de datos de fallas específicos para cada uno de los escenarios de excepción en su servicio WCF para que pueda manejar la falla/excepción en el lado del cliente, respectivamente.

+0

Soy nuevo en el que puede usted por favor dame un poco de enlace –

1
try 
{ 
    // Actions 
} 
catch (Exception ex) 
{ 
    // Log the exception 
    // Throw Fault Exception back to client 
    FaultException fe = new FaultException(ex.Message, new FaultCode("Your fault code")); 
    //throw fault exception back to WCF client 
    throw fe; 
}   
6
  1. crear una clase de error personalizado que está marcado con el atributo DataContract
  2. Marque la método en el servicio interfaz de contrato con FaultContract. Es decir.[FaultContract(typeof(CustomFault))]
  3. En su método de servicio, capture las excepciones internas aplicables y arroje FaultException<CustomFault>. Alternativamente, como mencionó marc_s, puede usar IErrorHandler para mapear la excepción a la falla.

Personalmente, creo una clase Fault base que tiene una propiedad Reason y extiendo todas las fallas personalizadas de esta clase. Cuando quiero echarle la culpa, que yo llamo:

throw Fault.Create<CustomFault>(new CustomFault("Boo hoo")); 

Es también digno de mención que la versión que mis clases de fallo (incluyendo la clase de fallo común), junto con el resto de mis servicios. Sin embargo, esto solo es una preocupación si el control de versiones del servicio es una preocupación.

Aquí está la clase básica de fallos (He quitado la validación de argumentos por razones de brevedad):

[DataContract(Namespace = XmlVersionNamespace.FaultNamespace)] 
public abstract class Fault 
{ 
    internal FaultReason Reason { get; set; } 

    protected Fault(string reasonText) 
    { 
     Reason = new FaultReason(new FaultReasonText(reasonText, CultureInfo.CurrentUICulture)); 
    } 

    public override string ToString() 
    { 
     return Reason.ToString(); 
    } 

    internal static FaultException<TDetail> Create<TDetail>(TDetail fault) where TDetail : Fault 
    { 
     return new FaultException<TDetail>(fault, fault.Reason); 
    } 
} 
+0

Gracias Richard! ¿Puede darme un ejemplo si supone que la autenticación falla? Solo dame la relación de clases de los barcos y cómo manejarás en la aplicación cliente. –

+0

Crearía un AuthenticationFailedFault (lo extenderé desde Fault), pasando un mensaje al constructor de fallas base. En su aplicación cliente, solo atrapa FaultException , ya que AuthenticationFailedFault formará parte del WSDL (siempre que marque el método con [FaultContract]) –

Cuestiones relacionadas