AggregateException和WCF

时间:2011-06-03 12:05:20

标签: c# wcf exception-handling

我正在调用WCF服务,该服务在某些条件下返回AggregateException,其中包含通过调用发生的所有问题

另一方面,我得到一个FaultException(这是有道理的,因为WCF只能理解这些异常)。问题是,合同的细节不是聚合例外。就好像默认情况下,WCF获取AggregateException异常列表(InnerExceptions)的第一个异常,并封装它。所以在客户端,我只是获得了列表的第一个例外。 经过调查,我做了以下几点:

将此添加到合同中

[FaultContract(typeof(AggregateException))]

然后在服务电话上..

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

但另一方面,就是这样:

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;
}

它正在进入异常catch语句,并得到这样的错误(这显然是一些随机错误,因为我没有任何连接问题,并且调试此立即返回,4分钟从未通过):

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

我缺少什么?

2 个答案:

答案 0 :(得分:1)

邪恶是,你的错误细节来自异常。阅读Using custom FaultContract object containing System.Exception causes 'Add Service Reference' to fail - mho。例如

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

然后FaultException<AggregateFault >完美但不是FaultException<AggregateException>

答案 1 :(得分:0)

我怀疑你的问题是在你遇到BaseService代码之前发生的,所以你实际上并没有抛出AggregateException。您需要确定抛出的异常,最简单的方法是在服务器上进行调试,下一个简单方法是连接一些日志记录。

如果你想能够轻松跟踪这些东西并且能够操纵故障等,那么最好的办法是实现IErrorHandler,我使用的基本实现通常遵循以下几行:

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.
    }
}

请注意,上面的代码不会完全满足您的AggregateException,但会让您走上正确的轨道,如果您选择沿着这条路线前进,还需要注入错误处理程序。