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

Ism*_*ilS 1 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 });
  }
}
Run Code Online (Sandbox Code Playgroud)

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

catch(FaultException<MyServiceFault> faultException)
{

}
Run Code Online (Sandbox Code Playgroud)

这是我的MyServiceFault

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

  [DataMember]
  public Guid Id { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

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

System.ServiceModel.CommunicationException: The underlying connection was closed: The connection was closed unexpectedly. ---> System.Net.WebException
Run Code Online (Sandbox Code Playgroud)

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

在我的web.config servicebehaviour标签组成 <serviceDebug includeExceptionDetailInFaults="true" />

知道我哪里出错了.

Windows 7上出现此问题.是否有与之相关的原因?

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

在WCF中记录异常的更好方法

Sim*_*ens 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>
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

try{
    x.Close()
}
catch(Comms ex){
    x.Abort()
}
Run Code Online (Sandbox Code Playgroud)