捕获通信异常而不是自定义故障异常 - WCF

时间:2010-04-26 09:05:16

标签: wcf exception-handling

在服务器上,我正在抛出这样的异常。

catch(SqlException exception)
{
  if (exception.Message.Contains("Custom error from stored proc"))
  {
    //Exception to be thrown when authentication fails.
    throw new FaultException<MyServiceFault>(new MyServiceFault { MessageText = exception.Message });
  }
}

在客户端,我正在捕捉异常

catch(FaultException<MyServiceFault> faultException)
{

}

这是我的MyServiceFault

[DataContract]
public class MyServiceFault  
{
  [DataMember]
  public string MessageText { get; set; }

  [DataMember]
  public Guid Id { get; set; }
}

问题是在客户端上,它不会转到MyServiceFault catch块而是转到通信异常catch块并抛出此错误

System.ServiceModel.CommunicationException: The underlying connection was closed: The connection was closed unexpectedly. ---> System.Net.WebException

我还在我的服务实现的界面中修饰了我的服务方法[FaultContract(typeof(MyServiceFault))]

在我的web.config servicebehaviour标记包中 <serviceDebug includeExceptionDetailInFaults="true" />

知道我哪里出错了。

Windows 7上出现此问题。是否存在与之相关的原因?

重要更新
根据回答者的说法,服务器上任何未处理的异常都可能导致在客户端抛出通信异常,并且它可能与您在服务器上抛出的自定义故障异常无关。因此,解决方案是在服务器上记录错误并找出导致此行为的错误。这是我发现并实现的一个非常有用的开源日志记录功能,在项目进入生产环境后甚至可以更有用。非常感谢回答者。

A better way of logging exceptions in WCF

3 个答案:

答案 0 :(得分:6)

通过在app.config中包含此内容,将日志记录添加到您的WCF调用中。

<system.diagnostics>
  <trace autoflush="true" />
  <sources>
    <source name="System.ServiceModel" switchValue="Information, ActivityTracing">
      <listeners>
        <add name="sdt" type="System.Diagnostics.XmlWriterTraceListener" initializeData="c:\LogPath\LogFile.svclog" />
      </listeners>
    </source>
  </sources>
</system.diagnostics>

(您可以为服务器和客户端执行此操作,显然指定不同的日志文件)

生成一些日志后,请查看异常或警告。我经常发现这会产生一些非常有用的信息,可以帮助我解决WCF问题。

要阅读日志文件,您需要使用SvcTraceViewer.exe。不幸的是,获得此功能的唯一方法是使用the windows SDK,这对于一个小小工具来说是一个很大的下载。

值得注意的是,WCF在关闭时可以通过CommunctionException,这是预期的行为。您不应该只使用客户端WCF通信通道using。相反,你应该遵循这样的模式:

try{
    x.Close()
}
catch(Comms ex){
    x.Abort()
}

答案 1 :(得分:4)

我从使用wcf中学到的一件事是,很多时候抛出错误CommunicationException。甚至有可能你得到的错误与你抛出的异常无关,而是与其他原因造成的。目前,在客户端和服务器之间发送了一些内容,很难找到导致异常的原因。

我可以通过调整app.config中的一些设置来解决我的一些问题。设置超时等...

也许这有帮助?

答案 2 :(得分:4)

作为后续行动,获取CommunicationException的一个原因是FaultException无法正确序列化。在日志中(参见Simon关于如何设置日志记录的答案),这将显示为“处理异常”,然后是“回复操作引发异常”

就我而言,这是因为没有初始化枚举值:

[DataContract]
public class MyCustomWebServiceFault
{
    public MyCustomWebServiceFault()
    {
    }

    [DataMember]
    public EMyCustomWebServiceFaultReason Reason { get; set; }

    [...]

然后日志显示它:

  

枚举值“0”对于“EMyCustomWebServiceFaultReason”类型无效,无法序列化。确保存在必要的枚举值,并且如果类型具有DataContractAttribute属性,则使用EnumMemberAttribute属性标记。

长话短说,使用日志记录或单元测试异常序列化。