2009-10-08 43 views
23

我在两台或多台远程计算机上部署了WCF服务,并且有一个基于桌面的应用程序供客户端用于访问任何wcf服务。在WCF服务中处理异常的最佳方法是什么?

WCF服务连接到SQL Server 2005以读取和写入数据。 这是客户端应该位于同一个域中的Intranet方案。

现在可以有场景中WCF服务抛出异常:

  1. 无效的URL
  2. WCF服务关闭
  3. SQL Server 2005是没有运行
  4. 客户是不是在同一个域
  5. 验证失败
  6. 授权失败

和许多其他例外。

对于每个异常,我必须执行一些操作或更新状态栏,具体取决于例外情况。例如,如果授权失败,我必须提示用户重新输入他们的凭证。

请提出最佳设计方法来处理此问题。

回答

32

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

这样,您不会“错误”(或推倒)您的客户端和服务器之间的通信通道。

更好的方法是在服务类上实现接口IErrorHandler,该接口提供了一种全局捕获所有异常的方法,并提供FaultException,而不是SOAPException。

你甚至可以将你的IErrorHandler变成一个可配置的行为,可以在config中打开或关闭。

请参阅以下文章和博客文章的详细信息:

+1

我不知道很多关于IErrorHandler但我读文章和使用IErrorHandler的帖子说它有一些缺点。在某些情况下,可能会直接从wcf服务向客户端抛出异常。你会推荐我IErrorHandler? – 2009-10-08 08:55:13

+0

是的,无论如何 - 我会**总是推荐使用IErrorHandler。你可以发布链接到这些文章,说它有缺点?从来没有听说过这些 - 我想调查.... – 2009-10-08 08:56:24

+0

http://stackoverflow.com/questions/265551/wcf-errorhandler 阅读第二篇文章!我不知道它是否正确,但它总是在我心中造成困惑 – 2009-10-08 09:01:28

2

您可以为WCF服务中的每个异常情况设计特定的故障数据合同,以便您可以分别处理客户端的故障/异常。

+0

我是新来的它,你可以请给我一些链接 – 2009-10-08 08:25:33

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; 
}   
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")); 

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

这里是基本的故障类(我已经删除了简洁参数验证):

[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); 
    } 
} 
+0

谢谢理查!如果认证失败,请给我一个例子。只要给我班级关系船和你将如何处理客户端应用程序.. – 2009-10-08 08:57:13

+0

我会创建一个AuthenticationFailedFault(从故障扩展它),将消息传递给基础Fault构造函数。在您的客户端应用程序中,您只需捕获FaultException ,因为AuthenticationFailedFault将成为WSDL的一部分(只要您使用[FaultContract]标记该方法) – 2009-10-08 10:09:53

相关问题