如何让 ELMAH 与 ASP.NET MVC [HandleError] 属性一起使用? [英] How to get ELMAH to work with ASP.NET MVC [HandleError] attribute?

查看:26
本文介绍了如何让 ELMAH 与 ASP.NET MVC [HandleError] 属性一起使用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 ELMAH 来记录我的 ASP.NET MVC 应用程序中的错误,但是当我在我的控制器上使用 [HandleError] 属性时,ELMAH 在它们发生时不会记录任何错误.

I am trying to use ELMAH to log errors in my ASP.NET MVC application, however when I use the [HandleError] attribute on my controllers ELMAH doesn't log any errors when they occur.

正如我猜测的那样,因为 ELMAH 只记录未处理的错误,而 [HandleError] 属性正在处理错误,因此无需记录.

As I am guessing its because ELMAH only logs unhandled errors and the [HandleError] attribute is handling the error so thus no need to log it.

我如何修改或我将如何修改属性,以便 ELMAH 可以知道存在错误并记录它..

How do I modify or how would I go about modifying the attribute so ELMAH can know that there was an error and log it..

让我确保每个人都理解,我知道我可以修改不是我要问的问题的属性......使用handleerror属性时ELMAH被绕过意味着它不会看到有一个错误,因为它已经由属性处理了......我问的是有没有办法让 ELMAH 看到错误并记录它,即使属性处理了它......我四处搜索但没有看看有什么方法可以调用来强制它记录错误....

Let me make sure everyone understands, I know I can modify the attribute thats not the question I'm asking... ELMAH gets bypassed when using the handleerror attribute meaning it won't see that there was an error because it was handled already by the attribute... What I am asking is there a way to make ELMAH see the error and log it even though the attribute handled it...I searched around and don't see any methods to call to force it to log the error....

推荐答案

您可以子类化 HandleErrorAttribute 并覆盖它的 OnException 成员(无需复制),以便它使用 ELMAH 记录异常,并且仅当基本实现处理它时.您需要的最少代码如下:

You can subclass HandleErrorAttribute and override its OnException member (no need to copy) so that it logs the exception with ELMAH and only if the base implementation handles it. The minimal amount of code you need is as follows:

using System.Web.Mvc;
using Elmah;

public class HandleErrorAttribute : System.Web.Mvc.HandleErrorAttribute
{
    public override void OnException(ExceptionContext context)
    {
        base.OnException(context);
        if (!context.ExceptionHandled) 
            return;
        var httpContext = context.HttpContext.ApplicationInstance.Context;
        var signal = ErrorSignal.FromContext(httpContext);
        signal.Raise(context.Exception, httpContext);
    }
}

首先调用基本实现,使其有机会将异常标记为正在处理.只有这样才会发出异常信号.上面的代码很简单,如果用在HttpContext可能不可用的环境中,比如testing,可能会出现问题.因此,您将需要更具防御性的代码(以稍长为代价):

The base implementation is invoked first, giving it a chance to mark the exception as being handled. Only then is the exception signaled. The above code is simple and may cause issues if used in an environment where the HttpContext may not be available, such as testing. As a result, you will want code that is that is more defensive (at the cost of being slightly longer):

using System.Web;
using System.Web.Mvc;
using Elmah;

public class HandleErrorAttribute : System.Web.Mvc.HandleErrorAttribute
{
    public override void OnException(ExceptionContext context)
    {
        base.OnException(context);
        if (!context.ExceptionHandled       // if unhandled, will be logged anyhow
            || TryRaiseErrorSignal(context) // prefer signaling, if possible
            || IsFiltered(context))         // filtered?
            return;

        LogException(context);
    }

    private static bool TryRaiseErrorSignal(ExceptionContext context)
    {
        var httpContext = GetHttpContextImpl(context.HttpContext);
        if (httpContext == null)
            return false;
        var signal = ErrorSignal.FromContext(httpContext);
        if (signal == null)
            return false;
        signal.Raise(context.Exception, httpContext);
        return true;
    }

    private static bool IsFiltered(ExceptionContext context)
    {
        var config = context.HttpContext.GetSection("elmah/errorFilter")
                        as ErrorFilterConfiguration;

        if (config == null)
            return false;

        var testContext = new ErrorFilterModule.AssertionHelperContext(
                              context.Exception, 
                              GetHttpContextImpl(context.HttpContext));
        return config.Assertion.Test(testContext);
    }

    private static void LogException(ExceptionContext context)
    {
        var httpContext = GetHttpContextImpl(context.HttpContext);
        var error = new Error(context.Exception, httpContext);
        ErrorLog.GetDefault(httpContext).Log(error);
    }

    private static HttpContext GetHttpContextImpl(HttpContextBase context)
    {
        return context.ApplicationInstance.Context;
    }
}

第二个版本将首先尝试使用来自 ELMAH 的错误信号,这涉及完全配置的管道,如日志记录、邮件发送、过滤以及您拥有的一切.如果失败,它会尝试查看是否应该过滤错误.如果不是,则简单地记录错误.此实现不处理邮件通知.如果可以发出异常信号,则将发送邮件(如果配置为这样做).

This second version will try to use error signaling from ELMAH first, which involves the fully configured pipeline like logging, mailing, filtering and what have you. Failing that, it attempts to see whether the error should be filtered. If not, the error is simply logged. This implementation does not handle mail notifications. If the exception can be signaled then a mail will be sent if configured to do so.

您可能还需要注意,如果多个 HandleErrorAttribute 实例有效,则不会发生重复日志记录,但以上两个示例应该可以帮助您入门.

You may also have to take care that if multiple HandleErrorAttribute instances are in effect then duplicate logging does not occur, but the above two examples should get your started.

这篇关于如何让 ELMAH 与 ASP.NET MVC [HandleError] 属性一起使用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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