WCF CommunicationException,没有Exception消息详细信息

时间:2011-09-13 15:29:01

标签: wcf communicationexception

我从未理解过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并没有什么不同。

1 个答案:

答案 0 :(得分:2)

我认为通过设计将服务器错误传播给客户端。这通常是不将服务器内部暴露给客户端的做法,因为Client Server体系结构的主要目的是服务器的独立性。

您仍然可以使用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

相关问题