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

Ash*_*shu 24 wcf

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

WCF服务连接到SQL Server 2005以读取和写入数据. 这是一个Intranet场景,其中客户端应位于同一域中.

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

  1. 无效的网址
  2. WCF服务已关闭
  3. SQL Server 2005未​​运行
  4. 客户端不在同一个域中
  5. 验证失败
  6. 授权失败

和许多其他例外.

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

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

mar*_*c_s 35

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

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

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

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

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

  • 好吧,我猜他期望太多了 - IErrorHandler将捕获在服务器上发生的所有异常 - 通信错误或安全设置不匹配,在服务器上不会发生 - 但在消息甚至到达服务器之前.这是一种不同的情况. (4认同)

Ric*_*lay 6

  1. 创建使用DataContract属性标记的自定义错误类
  2. 标记方法与服务合同接口上FaultContract.IE浏览器.[FaultContract(typeof(CustomFault))]
  3. 在您的服务方法中,捕获任何适用的内部异常并抛出FaultException <CustomFault>.或者,正如marc_s所提到的,您可以使用IErrorHandler将异常映射到故障.

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

throw Fault.Create<CustomFault>(new CustomFault("Boo hoo"));
Run Code Online (Sandbox Code Playgroud)

值得注意的是,我将我的故障类(包括常见的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);
    }
}
Run Code Online (Sandbox Code Playgroud)