2008-09-17 11 views
37

Actualmente estamos teniendo un debate sobre si es mejor lanzar fallas sobre un canal WCF, versus pasar un mensaje que indique el estado o la respuesta de un servicio.WCF - Fallas/Excepciones versus Mensajes

Las fallas vienen con el soporte integrado de WCF donde puede usar los manejadores de error incorporados y reaccionar en consecuencia. Esto, sin embargo, conlleva gastos generales, ya que arrojar excepciones en .NET puede ser bastante costoso.

Los mensajes pueden contener la información necesaria para determinar qué sucedió con su llamada de servicio sin la sobrecarga de lanzar una excepción. Sin embargo, necesita varias líneas de código repetitivo para analizar el mensaje y determinar las acciones que siguen a su contenido.

Nos tomó una puñalada en la creación de un objeto de mensaje genérico que podríamos utilizar en nuestros servicios, y esto es lo que se nos ocurrió:

public class ReturnItemDTO<T> 
{ 
    [DataMember] 
    public bool Success { get; set; } 

    [DataMember] 
    public string ErrorMessage { get; set; } 

    [DataMember] 
    public T Item { get; set; } 
} 

Si todas mis llamadas de servicio al volver este artículo, puedo comprobar constantemente la propiedad "Success" para determinar si todo salió bien. Luego tengo una cadena de mensaje de error en el evento que indica que algo salió mal, y un elemento genérico que contiene un Dto si es necesario.

La información de excepción se debe registrar en un servicio de registro central y no se debe volver a retransmitir desde el servicio.

¿Pensamientos? ¿Comentarios? Ideas? Sugerencias?

más aclaraciones sobre mi pregunta

Un problema que estoy teniendo con contratos de falla está comunicando reglas de negocio.

Me gusta, si alguien inicia sesión y su cuenta está bloqueada, ¿cómo la comunico? Su inicio de sesión obviamente falla, pero falla debido a la razón "Cuenta bloqueada".

yo también:

a) usar un valor lógico, tirar de fallos a cuenta de mensajes bloqueados

B) AuthenticatedDTO volver con información relevante

Respuesta

31

Sin embargo, esto conlleva gastos indirectos como lanzar excepciones en. NET puede ser bastante costoso.

Está serializando y deserializando objetos a XML y enviándolos a través de una red lenta ... la sobrecarga de lanzar una excepción es insignificante en comparación con eso.

normalmente se pegan a las excepciones de lanzamiento, ya que comunicar con claridad algo salió mal y todos kits de herramientas de servicio web tienen una buena manera de manejarlos.

En su ejemplo arrojaría una AccessException no autorizada con el mensaje "Cuenta bloqueada".

Aclaración: Los servicios .NET wcf traducen excepciones a FaultContracts de forma predeterminada, pero puede cambiar este comportamiento.MSDN:Specifying and Handling Faults in Contracts and Services

+0

No estoy de acuerdo. Como se supone que WCF es independiente del idioma (de alguna forma, al menos) no puede garantizar que pasar un objeto Exception por el cable no cause problemas, p. Ej. Clientes de Java. El tipo de objeto FaultContract puede garantizar la interoperabilidad ya que es parte de las especificaciones OASIS. – ZombieSheep

+4

.NET traduce las excepciones a los contratos de falla. Ver el enlace que agregué a mi respuesta. –

+0

Siempre tuve la impresión de que lanzar una excepción conllevaba gastos indirectos innecesarios. De su publicación, parece que estuve tristemente equivocado. Antes de marcar esta publicación como la siguiente, quiero obtener más opiniones. Pero teniendo en cuenta su opinión, parece que la falta de contrato es la mejor opción – WebDude

0

Consideraría seriamente el uso de los objetos FaultContract y FaultException para evitar esto. Esto le permitirá pasar mensajes de error significativos al cliente, pero solo cuando ocurra una falla.

Lamentablemente, estoy en un curso de capacitación por el momento, por lo que no puedo escribir una respuesta completa, pero por suerte, estoy aprendiendo acerca de la administración de excepciones en las aplicaciones de WCF. Voy a publicar esta noche con más información. (Lo siento es una respuesta débil)

6

Si piensa en llamar al servicio como si llamara a cualquier otro método, puede ayudar a poner las cosas en perspectiva. Imagine si cada método que llamó devuelve un estado, y usted depende de usted para verificar si es verdadero o falso. Sería bastante tedioso.

result = CallMethod(); 
if (!result.Success) handleError(); 

result = CallAnotherMethod(); 
if (!result.Success) handleError(); 

result = NotAgain(); 
if (!result.Success) handleError(); 

Este es uno de los puntos fuertes de un sistema de control de errores estructurado, es que se puede separar la lógica en cuestión de la gestión de errores. No tiene que seguir revisando, sabe que fue un éxito si no se emitió ninguna excepción.

try 
{ 
    CallMethod(); 
    CallAnotherMethod(); 
    NotAgain(); 
} 
catch (Exception e) 
{ 
    handleError(); 
} 

Al mismo tiempo, al devolver un resultado, usted está asignando más responsabilidades al cliente. Es probable que sepa verificar los errores en el objeto de resultado, pero John Doe entra y simplemente comienza a llamar a su servicio, sin darse cuenta de que algo está mal porque no se lanza una excepción. Esta es otra gran fortaleza de las excepciones: nos dan una buena bofetada cuando algo está mal y hay que ocuparse de ello.