Home Articles

在WCF服务中处理异常的最佳方法是什么?

Asked
Viewed 977 times
23

我在两台或多台远程计算机上部署了WCF服务,并且客户端使用基于桌面的应用程序来访问任何wcf服务 .

The WCF service is connected to SQL server 2005 to read and write data. 这是一个Intranet场景,其中客户端应位于同一域中 .

现在可能存在wcf服务抛出异常的情况:

  • 无效的网址

  • WCF服务已关闭

  • SQL Server 2005未运行

  • 客户端不在同一个域中

  • 身份验证失败

  • 授权失败

和许多其他例外 .

对于每个异常,我都必须执行某些操作或更新状态栏,具体取决于异常 . 例如,如果授权失败,我必须提示用户重新输入其凭据 .

请建议最好的设计方法来处理这个问题 .

4 Answers

  • 33

    您可以为WCF服务中的每个异常方案设计特定的故障数据协定,以便您可以分别在客户端处理故障/异常 .

  • 6
    • 创建标有DataContract属性的自定义故障类

    • 使用FaultContract标记服务 Contract 接口上的方法 . IE浏览器 . [FaultContract(typeof(CustomFault))]

    • 在您的服务方法中,捕获任何适用的内部异常并抛出FaultException<CustomFault> . 或者,正如marc_s所提到的,您可以使用IErrorHandler将异常映射到故障 .

    就个人而言,我创建了一个具有Reason属性的基类Fault类,并且我从此类扩展了所有自定义错误 . 当我想抛出错误时,我打电话给:

    throw Fault.Create<CustomFault>(new CustomFault("Boo hoo"));
    

    值得注意的是,我将我的故障类(包括常见的Fault类)与我的所有其他服务一起编辑 . 但是,如果服务版本控制是一个问题,这只是一个问题 .

    这是基本的Fault类(为简洁起见,我删除了参数验证):

    [DataContract(Namespace = XmlVersionNamespace.FaultNamespace)]
    public abstract class Fault
    {
        internal FaultReason Reason { get; set; }
    
        protected Fault(string reasonText)
        {
            Reason = new FaultReason(new FaultReasonText(reasonText, CultureInfo.CurrentUICulture));
        }
    
        public override string ToString()
        {
            return Reason.ToString();
        }
    
        internal static FaultException<TDetail> Create<TDetail>(TDetail fault) where TDetail : Fault
        {
            return new FaultException<TDetail>(fault, fault.Reason);
        }
    }
    
  • 2

    您绝对可以捕获并处理服务类上发生的所有异常,并将它们转换为FaultException或FaultException异常 .

    这样,您就不会“错误”(或拆除)客户端和服务器之间的通信通道 .

    更好的方法是在服务类上实现 IErrorHandler 接口,该接口提供了一种全局捕获所有异常的方法,并提供FaultException,这与SOAP兼容 .

    您甚至可以将 IErrorHandler 转换为可在配置中打开或关闭的可配置行为 .

    有关详细信息,请参阅这些文章和博文:

  • 1
    try
    {
      // Actions
    }
    catch (Exception ex)
    {
      // Log the exception
      // Throw Fault Exception back to client
      FaultException fe = new FaultException(ex.Message, new FaultCode("Your fault code"));
      //throw fault exception back to WCF client
      throw fe;
    }
    

Related