【问题标题】:WCF CommunicationException with no Exception message details没有异常消息详细信息的 WCF CommunicationException
【发布时间】:2011-09-13 15:29:01
【问题描述】:

关于 WCF,我从来不理解的一件事是,为什么当服务器遇到未处理的异常时,没有异常消息详细信息被传播回调用客户端。

例如,如果我有以下服务器代码

[ServiceBehavior(IncludeExceptionDetailInFaults = true)]
public class Server : IServer
{
    public DTO GetDTO()
    {
        DTO dto = new DTO();
        dto.dto = dto;
        return dto;
    }

}

public class DTO
{
    public DTO dto;
}

[ServiceContract]
public interface IServer
{
    [OperationContract]
    DTO GetDTO();
}

我特意引入了一个ObjectGraph,以便在返回DTO对象时引发序列化异常。

如果我有一个调用此服务器的GetDTO() 方法的客户端,我将得到以下CommunicationException

套接字连接被中止。这可能是由错误引起的 处理您的消息或接收超时被超过 远程主机或底层网络资源问题。本地插座 超时为“00:00:58.9350000”。

这绝对没用。它没有内部异常,甚至没有真正的异常消息。

如果您随后使用 Microsoft Service TraceViewer,您将看到异常,但您必须为此打开诊断跟踪。

应该发回的异常信息是

尝试序列化参数时出错 http://tempuri.org/:GetDTOResult。 InnerException 消息是 'TestWCFLib.DTO' 类型的对象图包含循环,不能 如果禁用引用跟踪,则序列化。'。请参见 InnerException 了解更多详情。

那么谁能告诉我如何在客户端显示正确的异常消息?显然,将 IncludeExceptionDetailInFaults 设置为 true 并没有什么不同。

【问题讨论】:

  • 我发现我在配置文件中设置了 IncludeExceptionDetailInFaults,但它被您在此处突出显示的数据注释所覆盖。您可以检查的另一个地方是您的 IIS 站点的错误页面配置。我将 500 错误功能设置始终设置为详细消息。

标签: wcf communicationexception


【解决方案1】:

我认为服务器错误不会传播给客户端是设计使然。这通常是一种不向客户端公开服务器内部结构的做法,因为客户端服务器架构的主要目的是服务器的独立性。

您仍然可以使用Fault Exception 实现此目的

用故障合同装饰您的服务声明

[ServiceContract]
public interface IServer
{
    [OperationContract]
    [FaultContract(typeof(MyApplicationFault))]
    DTO GetDTO();
}

然后在 servcie 实现中捕获错误并抛出错误异常。

[ServiceBehavior(IncludeExceptionDetailInFaults = true)]
    public class Server : IServer
    {
        public DTO GetDTO()
        {
            try
              {
                   DTO dto = new DTO();
                   dto.dto = dto;
                   return dto;
               }
            catch (Exception ex)
                 {
                     MyApplicationFault fault = new MyApplicationFault(...);
                     throw new FaultException<MyApplicationFault>(fault);
                 }
        }

    }

并在客户端捕获异常

IServer proxy = ...;    //Get proxy from somewhere
try 
{
    proxy.GetDTO();
}
catch (TimeoutException) { ... }
catch (FaultException<MyApplicationFault> myFault) {
    MyApplicationFault detail = myFault.Detail;
    //Do something with the actual fault
}
catch (FaultException otherFault) { ... }
catch (CommunicationException) { ... }

希望这会有所帮助。 好的教程请看Code Project Tutorial on Fault Exception

【讨论】:

  • CommunicationException 是 von FaultException 的超类型,因此应该更改捕获的顺序。
  • @uli78 是的。已更正。谢谢。
猜你喜欢
  • 2013-10-08
  • 2011-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多