异常记录使用ELMAH WCF服务 [英] Exception Logging for WCF Services using ELMAH

查看:162
本文介绍了异常记录使用ELMAH WCF服务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们正在使用的优秀 ELMAH 来处理在ASP.NET 3.5 Web应用程序未处理的异常。这个作品非常好所有的WCF服务除了网站正在被使用REST功能消耗。当一个异常不是由应用程序code处理的操作方法中发生,WCF处理它在根据服务合同和配置设置的各种方式。这意味着该异常不会结束击发该 ELMAH 的使用ASP.NET HttpApplication.Error事件。这两种方案我知道对付这种是:

We are using the excellent ELMAH to deal with unhandled exceptions in an ASP.NET 3.5 web application. This works extremely well for all of the site apart from WCF services which are being consumed using the REST features. When an exception occurs within the operation methods that is not handled by the application code, WCF handles it in various ways depending on the service contracts and configuration settings. This means that the exception does not end up firing the ASP.NET HttpApplication.Error event that ELMAH uses. The two solutions I am aware of to deal with this are:


  • 总结所有方法调用在try {}赶上(例外前){Elmah.ErrorSignal.FromCurrentContext()提高(前)。扔; }到catch块中显式调用ELMAH。

  • 使用<一个href=\"http://msdn.microsoft.com/en-us/library/system.servicemodel.dispatcher.ierrorhandler.aspx\">IErrorHandler如威尔·休斯的博客帖子的制作WCF和ELMAH一起玩好的分解出调用ELMAH到一个单独的ErrorHandler。

  • Wrap all method calls in a try { } catch(Exception ex) { Elmah.ErrorSignal.FromCurrentContext().Raise(ex); throw; } to explicitly call Elmah within the catch block.
  • Use IErrorHandler as described in Will Hughes' blog post Making WCF and ELMAH play nice together to factor out the call to ELMAH to a separate ErrorHandler.

第一个选项是非常简单的,但不完全是 DRY 。第二个选项只需要你实现属性和之后的ErrorHandler装饰与自定义属性的每个服务。我这样做基于威尔的工作,但我想验证这是否是在正确的做法张贴code之前。

The first option is extremely simple but is not exactly DRY. The second option only requires you to decorate each service with the custom attribute after implementing the attribute and the ErrorHandler. I have done this based on Will's work but I want to verify that this is the correct approach before posting the code.

有没有办法,我已经错过了一个更好的办法?

在MSDN documenation为<一个href=\"http://msdn.microsoft.com/en-us/library/system.servicemodel.dispatcher.ierrorhandler.aspx\">IErrorHandler说,在的HandleError 的方法是可以做,但 ELMAH 访问记录的地方HttpContext.Current。 ApplicationInstance ,它即使HttpContext.Current可用此方法中为空。在ProvideFault方法中进行调用,以ELMAH是ApplicationInstance设置的方法,但这种不匹配API文档中描述的意图。 我失去了一些东西在这里?的文件不被调用的操作线程,你不应该依靠的HandleError方法状态,这可能是为什么ApplicationInstance在此范围内空。

The MSDN documenation for IErrorHandler says that the HandleError method is the place to do the logging but ELMAH accesses the HttpContext.Current.ApplicationInstance, which is null within this method even though HttpContext.Current is available. Making the call to Elmah within the ProvideFault method is a workaround as ApplicationInstance is set but this does not match the intent described in the API documentation. Am I missing something here? The documentation does state that you should not rely on the HandleError method being called on the operation thread which may be why ApplicationInstance is null in this scope.

推荐答案

这是我的博客文章(在OP引用),该解决方案是基于过程中我们/使用改变HTTP响应codeS现有的解决方案错误状态。

The solution from my blog post (referenced in the OP) was based on an existing solution we were/are using to alter HTTP Response Codes during an error state.

所以,对我们来说是一个单行变化异常传递给ELMAH。如果有一个更好的解决办法,我很想知道这一点。

So, for us it was a one-line change to pass the Exception to ELMAH. If there's a better solution, I'd love to know about it too.

有关后人/参考和潜在的改进 - 这里是从目前的解决方案code。

For Posterity/Reference, and potential improvement - here's the code from the current solution.

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服务:

Usage Example

Decorate your WCF Services with the ServiceErrorBehaviour Attribute:

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

这篇关于异常记录使用ELMAH WCF服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆