asp.net - 使用 ELMAH 记录 WCF 服务的异常

标签 asp.net wcf exception logging elmah

我们正在使用优秀的ELMAH处理 ASP.NET 3.5 Web 应用程序中未处理的异常。这对于除使用 REST 功能使用的 WCF 服务之外的所有站点都非常有效。当操作方法中发生应用程序代码未处理的异常时,WCF 根据服务契约和配置设置以各种方式进行处理。这意味着该异常最终不会触发 ELMAH 的 ASP.NET HttpApplication.Error 事件。用途。我知道处理这个问题的两个解决方案是:

第一个选项非常简单,但并不完全是 DRY 。第二个选项只需要您在实现属性和 ErrorHandler 后使用自定义属性来装饰每个服务。我是根据 Will's 这样做的工作,但我想在发布代码之前验证这是正确的方法

有我错过的更好的方法吗?

IErrorHandler 的 MSDN 文档说 HandleError 方法是进行日志记录的地方,但是 ELMAH访问 HttpContext.Current.ApplicationInstance,即使 HttpContext.Current 可用,该方法在此方法中仍为 null。在 ProvideFault 方法中调用 Elmah 是一种解决方法,因为已设置 ApplicationInstance,但这与 API 文档中描述的意图不符。 我在这里遗漏了什么吗?文档确实指出您不应该依赖在操作线程上调用的 HandleError 方法,这可能就是 ApplicationInstance 在此范围内为 null 的原因。

最佳答案

我的博客文章中的解决方案(在 OP 中引用)基于我们曾经/正在用来在错误状态期间更改 HTTP 响应代码的现有解决方案。

因此,对于我们来说,将异常传递给 ELMAH 只需一行更改。如果有更好的解决方案,我也很想知道。

供后代/引用和潜在改进 - 这是当前解决方案的代码。

HttpErrorHandler 和 ServiceErrorBehaviourAttribute 类

using System;
using System.ServiceModel;
using System.ServiceModel.Dispatcher;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.Collections.ObjectModel;
using System.Net;
using System.Web;
using Elmah;
namespace YourApplication
{
    /// <summary>
    /// Your handler to actually tell ELMAH about the problem.
    /// </summary>
    public class HttpErrorHandler : IErrorHandler
    {
        public bool HandleError(Exception error)
        {
            return false;
        }

        public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
        {
            if (error != null ) // Notify ELMAH of the exception.
            {
                if (System.Web.HttpContext.Current == null)
                    return;
                Elmah.ErrorSignal.FromCurrentContext().Raise(error);
            }
        }
    }
    /// <summary>
    /// So we can decorate Services with the [ServiceErrorBehaviour(typeof(HttpErrorHandler))]
    /// ...and errors reported to ELMAH
    /// </summary>
    public class ServiceErrorBehaviourAttribute : Attribute, IServiceBehavior
    {
        Type errorHandlerType;

        public ServiceErrorBehaviourAttribute(Type errorHandlerType)
        {
            this.errorHandlerType = errorHandlerType;
        }

        public void Validate(ServiceDescription description, ServiceHostBase serviceHostBase)
        {
        }

        public void AddBindingParameters(ServiceDescription description, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection parameters)
        {
        }

        public void ApplyDispatchBehavior(ServiceDescription description, ServiceHostBase serviceHostBase)
        {
            IErrorHandler errorHandler;
            errorHandler = (IErrorHandler)Activator.CreateInstance(errorHandlerType);
            foreach (ChannelDispatcherBase channelDispatcherBase in serviceHostBase.ChannelDispatchers)
            {
                ChannelDispatcher channelDispatcher = channelDispatcherBase as ChannelDispatcher;
                channelDispatcher.ErrorHandlers.Add(errorHandler);
            }
        }
    }
}

使用示例

使用 ServiceErrorBehaviour 属性装饰您的 WCF 服务:

[ServiceContract(Namespace = "http://example.com/api/v1.0/")]
[ServiceErrorBehaviour(typeof(HttpErrorHandler))]
public class MyServiceService
{
  // ...
}

关于asp.net - 使用 ELMAH 记录 WCF 服务的异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/895901/

相关文章:

c# - NServiceBus 在此 WCF MVC 场景中有用吗?

c# - HttpModule 和 WCF (AspNetCompatibilityRequirementsMode.Allowed)

c# - 如何使用 Java 客户端导入 WCF Web 服务

java - 在 Java Swing 应用程序中嵌入 Log4j 和 AOP 以进行异常日志记录

c++ - 为什么抛出的对象必须进行复制初始化?

javascript - ASP.NET RadioButtonList 和渐进式增强

asp.net - azure 部署问题:do not have permission to view this directory or page

asp.net - 做太多事情的网页

java - 扫描仪异常重试

c# - 是否仍然可以使用仅适用于完整 .NET Framework 的 .NET Core 2.0 模板创建 Web 应用程序