技术开发 频道

WCF中的异常处理

   
   我们可以将服务所要抛出的异常类型作为FaultException<T>的类型参数,然后创建一个FaultReason对象用以传递错误消息。客户端在调用服务代理对象时,可以捕获FaultException< DirectoryNotFoundException>异常,并且该异常不会使得通道发生错误,并且客户端可以继续使用该服务代理对象。即使服务为PerCall服务,客户端仍然可以继续调用服务操作。如果服务为Session服务或Singleton服务,那么即使发生了异常,服务对象也不会被终结。

   如果只是为了让客户端获得异常消息,即使不施加FaultContract特性,或者抛出非FaultException异常,我们也可以通过ServiceBehavior特性,将服务的IncludeExceptionDetailInFaults设置为true(默认为false),此时,客户端可以捕获抛出的非FaultException异常信息,但该异常仍然会导致通道出现错误。

   但是,在发布服务与部署服务时,我们应避免将服务的IncludeExceptionDetailInFaults设置为true。

   如果不希望使用FaultContract,同时又要保证服务抛出的异常能够被客户端捕获,并且不会导致通道错误,我们还可以通过错误处理扩展的方式实现。此时,我们可以将服务本身作为错误处理对象,令其实现System.ServiceModel.Dispatcher.IErrorHandler接口: 
public class DocumentsExplorerService : IDocumentsExplorerService,IErrorHandler, IDisposable 
{…}

    在该接口的ProvideFault()方法中,可以将非FaultContract异常提升为FaultContract<T>异常,例如将DirectoryNotFoundException异常提升为FaultExceptino<DirectoryNotFoundException>异常:
public void ProvideFault(Exception error, MessageVersion version, ref Message fault) 
{
if (error is DirectoryNotFoundException)
{
FaultException<DirectoryNotFoundException> faultException = new FaultException<DirectoryNotFoundException>(
new DirectoryNotFoundException(), new FaultReason(error.Message));
MessageFault messageFault = faultException.CreateMessageFault();
fault = Message.CreateMessage(version,messageFault,faultException.Action);
}
}
  
 而在该接口的HandleError()方法中,则可以处理异常错误,例如记录日志。

  要使得错误处理扩展生效,还需要向服务通道安装错误处理扩展。方法是让服务类实现System.ServiceModel.Description.IServiceBehavior接口:
public class DocumentsExplorerService : IDocumentsExplorerService,IErrorHandler,IServiceBehavior,IDisposable

0
相关文章