【问题标题】:AggregateException and WCF聚合异常和 WCF
【发布时间】:2011-09-07 18:50:40
【问题描述】:

我正在调用 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;
}

它进入了 Exception 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

我错过了什么?

【问题讨论】:

  • 您是否尝试过通过调试器来确定实际抛出了什么异常?

标签: c# wcf exception-handling


【解决方案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&lt;AggregateFault &gt; 工作完美但不是FaultException&lt;AggregateException&gt;

【讨论】:

    【解决方案2】:

    我怀疑您的问题是在您点击 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 但会让您走上正确的轨道,如果您选择走这条路,您还需要注入错误处理程序。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-24
      相关资源
      最近更新 更多