【问题标题】:WCF global exception handlingWCF 全局异常处理
【发布时间】:2011-07-12 14:41:07
【问题描述】:

我已经为我的 wcf 应用程序构建了一个全局异常处理。我有一个实现“IErrorHandler”并处理异常的类。我可以使用“IServiceBehavior”属性注册 ErrorHandler。 (所以我不需要触摸每个功能)

我使用“FaultException”类来包装我的异常对象。

Dim sysEx As SystemException = 'Do Convert
Dim fex As New FaultException(Of SystemException)(sysEx, sysEx.Message)
Dim faultMessage As MessageFault = fex.CreateMessageFault
fault = System.ServiceModel.Channels.Message.CreateMessage(version, faultMessage, fex.Action)

现在我可以在客户端检索错误消息。但不幸的是,我无法检索原始异常类型或原始堆栈跟踪。

是否有一个简单的选项可以在不向我的服务中的每个函数添加“FaultContract”的情况下解决问题?

谢谢

【问题讨论】:

    标签: .net vb.net visual-studio wcf


    【解决方案1】:

    Steve 和 Saravanan 都是正确的。以下是如何创建自定义故障类型以及如何使用它:

    自定义故障合约:

    [DataContract]
    public class UncaughtErrorFault
    {
        [DataMember]
        public string ExecptionType { get; set; }
    
        [DataMember]
        public string Message { get; set; }
    
        [DataMember]
        public string StackTrace { get; set; }
    }
    

    IErrorHandler 方法覆盖:

    public void ProvideFault(Exception error,
                             MessageVersion version,
                             ref Message fault)
    {
        var fe = new FaultException<UncaughtErrorFault>(
            new UncaughtErrorFault
                {
                    ExecptionType = error.GetType().Name,
                    Message = error.Message,
                    StackTrace = error.StackTrace
                },
            error.Message,
            FaultCode.CreateReceiverFaultCode(
                new FaultCode(error.GetType().Name)));
    
        var mf = fe.CreateMessageFault();
    
        fault = Message.CreateMessage(version, mf, fe.Action);
    }
    

    【讨论】:

    • 也许我表达错了。如何将“UncaughtErrorFault”类“发布”到客户端?该类型不会添加到自动生成的“服务引用”中(当然)。因此,WCF 将故障转换回正常的 System.Exception 而不是“UncaughtErrorFault”对象。我该如何解决这个问题?
    • 要发布您的自定义故障,请查看MSDN article。它显示了如何使用指定自定义类型的 FaultContract 属性来标记服务 OperationContract 方法。但是,您需要标记服务的每个操作方法以使服务引用包含必要的反序列化代码。这就是我在对@SteveWilkes 的评论中所指的
    【解决方案2】:

    使用FaultContracts 并使用自定义Fault 类型抛出FaultExceptions 是在WCF 中处理异常的the recommended way。如果您需要在客户端检索堆栈跟踪,您可以在 WCF 行为配置中将 includeExceptionDetailInFaults 设置为 true。

    【讨论】:

    • 不幸的是,该服务可以抛出正常的 .NET 异常,并且有一些“封闭源”部分也会抛出正常的 .NET 异常。因此,我需要一种通用且易于处理的方法将 .NET 异常转换为 SOAP 错误。为此,我编写了上面的代码。不幸的是,我不知道如何创建一个可以包含更多属性的自定义故障,而无需将 FaultContract 添加到每个函数。
    • 除非您希望 WCF 抛出该自定义错误,否则您无需向操作方法添加 FaultContract 属性。您始终可以捕获标准 WCF FaultException,因为您的自定义错误已“嵌入”其中。您可以为 FaultException 类型编写一个扩展方法来提取您提供的任何自定义信息。
    【解决方案3】:

    在 IErrorHandler.ProvideFault 中,您在第一个参数中得到了异常。您可以将其包装在您的自定义 FaultMessage 中。

    IErrorHandler.ProvideFault(Exception error, MessageVersion ver, ref Message fault)

    请参考IErrorHandler Interface。本页提供了一个关于如何进行异常包装的示例。

    【讨论】:

      猜你喜欢
      • 2016-11-03
      • 2015-12-21
      • 2011-09-29
      • 2011-06-17
      • 1970-01-01
      • 1970-01-01
      • 2011-12-26
      • 2016-02-12
      相关资源
      最近更新 更多