代码之家  ›  专栏  ›  技术社区  ›  Graham Clark

WCF FaultException-从内部WCF调用“重新抛出”时崩溃应用程序池

  •  0
  • Graham Clark  · 技术社区  · 14 年前

    我有一个托管在IIS中的WCF服务,它使用WS-HTTP绑定(外部服务)。此服务最终通过nettcp(内部服务)调用另一个WCF服务,该服务托管在Windows服务中。当内部服务抛出 FaultException ,外部服务崩溃,而不是将其扔给客户端。客户端看到的只是连接被强制关闭。

    FaultException<ValidationFault>

    内部和外部服务都有一个 [FaultContract(typeof(ValidationFault)] 服务合同中的属性。如果我把外部服务改成直接抛出一个新的 FaultException<ValidaitonFault>

    外部服务用来与内部服务通信的客户机对象肯定已被关闭并正确处理。如何将内部服务的错误传播到客户机?

    更新时间:

    下面是外部服务代码的简化版本。我可以从内部服务呼叫中发现验证错误。如果我扔一个全新的 故障异常<验证故障> ,一切都很好。如果使用捕获的异常,则与外部客户机的连接断开。我能看到的唯一区别是在调试服务时-尝试使用捕获的异常会导致在退出方法时出现一个消息框,其中

    类型的未处理异常 '系统.ServiceModel.FaultException'1'

    如果我抛出一个全新的异常,就不会出现这种情况。也许答案是手动将验证错误的细节复制到一个新对象中,但这似乎很疯狂。

    public class ExternalService : IExternalService
    {
       public ExternalResponse DoSomething(ExternalRequest)
       {
          try
          {
             var response = new ExternalResponse();
             using (var internalClient = new InternalClient())
             {
                response.Data = internalClient.DoSomething().Data;
             }
    
             return response;
          }
          catch (FaultException<ValidationFault> fEx)
          {
             // throw fEx;   <- crashes
    
             // throw new FaultException<ValidationFault>(
             //    fEx.Detail as ValidationFault);   <- crashses
    
             throw new FaultException<ValidationFault>(
                new ValidationFault(new List<ValidationDetail> {
                   new ValidationDetail("message", "key", "tag") }),
                   "fault message", new FaultCode("faultCode"))); // works fine!
          }
       }
    }
    
    2 回复  |  直到 14 年前
        1
  •  0
  •   Randy Levy    14 年前

    我的设计和你差不多,遇到了一个类似的问题(但不确定会不会发生车祸!)。

    ValidationFault 是一个常见的类,当故障在导线上传播时,其类型特定于WCF接口。我认为这是因为web服务上的命名空间限定符(但这是很久以前的事了,所以我可能弄错了)。

    它并不十分优雅,但我所做的是手动重新抛出异常:

    try
    {
        DoStuff();
    }
    catch (FaultException<ValidationFault> fe)
    {
        HandleFault(fe);
        throw;
    }
    
    ...
    
    private void HandleFault(FaultException<ValidationFault> fe)
    {
        throw new FaultException<ValidationFault>(fe.Detail as ValidationFault);
    }
    
        2
  •  0
  •   Graham Clark    14 年前

    好吧,如果我这样做的话,它是有效的,但一定有更好的方法。。。

    FaultException<ValidationFault> . 我可以再扔一次 FaultException FaultException<SomethingElse> 没有问题的对象。

    try
    {
       DoStuff();
    }
    catch (FaultException<ValidationFault> fe)
    {
       throw this.HandleFault(fe);
    }
    
    ...
    
    private FaultException<ValidationFault> HandleFault(
        FaultException<ValidationFault> fex)
    {
        var validationDetails = new List<ValidationDetail>();
        foreach (ValidationDetail detail in fex.Detail.Details)
        {
            validationDetails.Add(detail);
        }
    
        return new FaultException<ValidationFault>(
            new ValidationFault(validationDetails));
    }