2011-06-03 22 views
6

Voy a llamar a un servicio WCF, que bajo ciertas condiciones devuelve un AggregateException, con todos los problemas que ocurrieron a través de la llamadaAggregateException y WCF

Por otro lado, me estoy poniendo un FaultException (lo cual tiene sentido , porque WCF solo entiende estas excepciones). El problema es que el detalle del contrato no es una excepción agregada. Es como si, de forma predeterminada, WCF obtiene la primera excepción para la lista de excepción de Extract de Aggregate (InnerExceptions), y lo encapsula. Entonces, en el lado del cliente, estoy obteniendo la primera excepción de la lista. Después de investigar un poco, hice lo siguiente:

añadido este al contrato

[FaultContract(typeof(AggregateException))] 

A continuación, en la llamada de servicio ..

try 
{ 
    BaseService.Blabla.Delete(item); 
} 
catch (AggregateException ex) 
{ 
    throw new FaultException<AggregateException>(ex); 
} 

Pero, por otro lado, que es la siguiente :

catch (FaultException<AggregateException> ex) 
{ 
    string msg = string.Empty; 
    foreach (var innerException in ex.Detail.InnerExceptions) 
    { 
     msg += innerException + Environment.NewLine; 
    } 
    MessageBox.Show(msg); 
} 
catch (Exception ex) 
{ 
    throw ex; 
} 

Está entrando en la declaración catch de excepción en su lugar, una d conseguir un error como este (que obviamente es un error aleatorio, porque yo no tengo problemas de conexión, y la depuración de esto devuelve inmediatamente, 4 minutos no pasan):

The socket connection was aborted. This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue. Local socket timeout was '00:03:59.9939994'. : An existing connection was forcibly closed by the remote host 

¿Qué me falta?

+0

Ha intentado entrar por el depurador para determinar qué excepción que realmente está siendo lanzado? –

Respuesta

0

Sospecho que su problema está ocurriendo antes de que llegue al código BaseService, por lo que no está lanzando realmente una AggregateException. Debe determinar qué excepción se está lanzando, la forma más fácil es depurar en el servidor, el siguiente paso es conectar un poco de registro.

Si usted quiere ser capaz de seguir fácilmente estas cosas y tienen la capacidad de manipular fallos etc Lo mejor es poner en práctica IErrorHandler, una implementación básica que utilizo normalmente va en los siguientes términos:

public class ErrorHandler : IErrorHandler 
{ 
    private readonly Action<Exception> LogException; 
    private readonly Action<Message> LogFault; 

    public ErrorHandler(Action<Exception> logException, Action<Message> logFault) 
    { 
     LogException = logException; 
     LogFault = logFault; 
    } 

    public void ProvideFault(Exception error, MessageVersion version, ref Message fault) 
    { 
     if (error is FaultException) // Thrown by WCF - eg request deserialization problems, can be explicitly thrown in code 
     { 
      LogFault(fault); 
      return; 
     } 

     var faultCode = new FaultCode("UnknownFault"); 
     if (error is ArgumentOutOfRangeException) 
     { 
      faultCode = new FaultCode("ArgumentOutOfRange"); 
     } 

     var action = OperationContext.Current.IncomingMessageHeaders.Action; 
     fault = Message.CreateMessage(version, faultCode, error.Message, action); 
     LogFault(fault); 
    } 

    public bool HandleError(Exception error) 
    { 
     // Logging of exceptions should occur here as all exceptions will hit HandleError, but some will not hit ProvideFault 
     LogException(error); 

     return false; // false allows other handlers to be called - if none return true the dispatcher aborts any session and aborts the InstanceContext if the InstanceContextMode is anything other than Single. 
    } 
} 

Tenga en cuenta que el código anterior no servirá exactamente para su AggregateException, pero le guiará por el camino correcto, también necesitará inyectar el controlador de errores si elige seguir esta ruta.