AggregateException and WCF
本文关键字:WCF and AggregateException | 更新日期: 2023-09-27 17:58:16
我正在调用WCF服务,该服务在某些条件下返回AggregateException,其中包含通过调用发生的所有问题
另一方面,我得到了一个FaultException(这是有道理的,因为WCF只了解这些异常)。问题是,合同的细节并不是一个总的例外。就好像在默认情况下,WCF获得AggregateException异常列表(InnerException)的第一个异常,并封装它。所以在客户端,我只是得到了列表中的第一个例外。经过一点调查,我做了以下事情:
将此添加到合同中
[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
我错过了什么?
问题是,您的错误细节源自异常。已阅读使用包含系统的自定义FaultContract对象。异常原因';添加服务参考';失败–mho。例如
[DataContract]
public class AggregateFault
{
[DataMember]
public string Message { get; set; }
}
则CCD_ 1是完美的,而不是CCD_ 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,但会让您走上正轨,如果您选择走这条路,您还需要注入错误处理程序。