zoukankan      html  css  js  c++  java
  • WCF的错误处理

    编写中...........
    一、使用FaultContract
    1、WCF通过提供FaultContract特性指明操作可能会抛出的异常类型,只有通过该特性指明的类型才会有可能在服务调用出现异常时把该类型序列化传递给调用方。例如定议了一个Contract如下:
        [ServiceContract]
        
    public interface IRequestClient
        
    {
            [OperationContract]
            [FaultContract(
    typeof(System.Exception))]
            [FaultContract(
    typeof(System.Net.WebException))]
            [FaultContract(
    typeof(ExceptionDetail))]
            
    string RequestContent(string clientID, string sourceID, string handleMode, string identity);
        }
    方法RequestContent可能在调用过程中会抛出的各种异常,但是需要通过FaultContract来预先指定。当然这里就会有很强的耦合,解决方法会在第二种解决方案中给出。
    2、虽然指定了RequestContent特性,但是但如果服务抛出的异常并不是FaultException或者FaultException<T>异常,会异常WCF的通信通导发生错误从而使得抛出CommunicationObjectFaultedException异常,无法继续使用服务。所以在实际的服务中可以把你想要传递的异常封装为FaultException或者FaultException<T>类型抛出,然后在客户端截获这种类型。使用ActionClientAcceptIClientAccept的实现,它抛出的异常就是经过封装的。
        [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, IncludeExceptionDetailInFaults = true)]
        
    public class ActionClientAccept : IClientAccept
        
    {
            
    public bool AcceptContent(string clientID, string sourceID, string handleMode, string identity, string content)
            
    {
                
    try
                
    {
            
    throw new NotImplementedException("测试");
                }

                
    catch (Exception ex)
                
    {
                    ExceptionDetail detail 
    = new ExceptionDetail(ex);
                    
    throw new FaultException<ExceptionDetail>(detail, ex.Message);
                }

            }

         }
    注意:这里我们还使用了一个ExceptionDetail对异常进行了封装,这样的好处是

    二、使用IErrorHandlerIServiceBehavior接口实现错误处理扩展。
    服务的实现类ActionClientAccept通过实现IErrorHandler接口,可以把一般的异常提升为FaultException或者FaultException<T>异常,通过这样的方式,就可以不需要在IRequestClient中定义FaultContract特性,从而实现了一定程度的解藕,例子如下:
        [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, IncludeExceptionDetailInFaults = true)]
        
    public class ActionClientAccept : IClientAccept, IErrorHandler, IServiceBehavior
        
    {
            
    public bool AcceptContent(string clientID, string sourceID, string handleMode, string identity, string content)
            
    {
            
    throw new NotImplementedException();
            }


            
    IErrorHandler Members

            
    IServiceBehavior Members
        }
    HandleError方法的调用是通过一个单独的线程来进行的,也就是说你可以在这个地方把错误写入日志,或者传递到别处,即使操作耗时也不会影响到主线程。
    ProvideFault方法的调用是用来把一般的异常得升为FaultException和FaultException<T>,这样就不需要在Contract中设置各种不同的FaultException了,注意到方法中调用了PromoteException方法的封装是来自于<<WCF服务编程>>,最后会以附件的形式给出。
    现在,已经得到了IErrorHandler的实现了,但是如何把它附加到通道中呢,其实也就是简单的在服务实现类中实现IServiceBehavior就可以在服务初始加载中自动的加载到错误处理器中,我们只需要关于其中的ApplyDispatchBehavior方法就可以了,例如:
                foreach (ChannelDispatcher dispatcher in serviceHostBase.ChannelDispatchers)
                
    {
                    dispatcher.ErrorHandlers.Add(
    this);
                }
    把IServiceBehavior的实现分别添加到服务的通过分发器的错误处理器中。
    通过这样的方法可以很容易的把异常发送给客户端了,不过服务器端抛出的异常还是必须封装成FaultException或者FaultException<T>方法的,在客户端也需要捕捉这样的异常,这一点要注意。
    ErrorHandlerHelper类的定义如下:
        public static class ErrorHandlerHelper
        


    三、自定义ErrorHandlerBehavior特性


    参考:
    <<WCF服务编程>>
    WCF中的异常处理

    补充:如何设定includeExceptionDetailInFaults?
    1、使用ServiceBehaviorAttribute
    [ServiceBehavior(IncludeExceptionDetailInFaults = true)]

    public class SpecialProvider : ISpecialProvider

    2、编码设定
    ServiceDebugBehavior debug = serviceHost.Description.Behaviors.Find<ServiceDebugBehavior>();
    debug.IncludeExceptionDetailInFaults 
    = true;
    3、写配置文件
    <?xml version="1.0" encoding="utf-8" ?>
      
    <system.serviceModel>
        
    <services>
          
    <service name="XXXService" behaviorConfiguration="XXXServiceBehavior"></services>
        
    <behaviors>
          
    <serviceBehaviors>
            
    <behavior name="XXXServiceBehavior">
              
    <serviceDebug httpHelpPageEnabled="True" includeExceptionDetailInFaults="True"/>
            
    </behavior>
          
    </serviceBehaviors>
        
    </behaviors>
      
    </system.serviceModel>

  • 相关阅读:
    笨方法学python(本文为阅读时从此书摘录的笔记) 第一天
    关于C++中的虚拟继承的一些总结
    用提高效率的暴力法求3000以内的素数
    DAY 155 python中parse模块
    DAY 154 python自带的hmac模块
    DAY 153 Python中使用pymongo操作mongodb
    DAY 152 hmac模块
    DAY 151 parse模块
    DAY 150 setter&getter&@property
    DAY 149 property和setter装饰器
  • 原文地址:https://www.cnblogs.com/chenjunbiao/p/1760209.html
Copyright © 2011-2022 走看看