4

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

4

1 回答 1

2

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

您仍然可以通过使用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) { ... }

希望这可以帮助。有关不错的教程,请参阅有关故障异常的代码项目教程

于 2012-12-04T08:34:32.740 回答