现在NuGet中有一个ELMAH.MVC包,其中包括Atif改进的解决方案,以及一个控制器来处理MVC路由中的elmah接口(不需要再使用那个axd)。
该解决方案(以及所有这里提到的解决方案)的问题在于,无论如何elmah错误处理程序实际上都会处理错误,忽略您可能想设置为自定义错误标记或通过ErrorHandler或自己的错误处理程序设置的内容。我认为最好的解决方案是创建一个过滤器,在所有其他过滤器的末尾起作用,并记录已处理的事件。 elmah模块应该负责记录应用程序未处理的其他错误。这也将使您能够使用健康监视器和可以添加到asp.net中查看错误事件的所有其他模块。
我查看了elmah.mvc中的ErrorHandler,写下了这篇文章。
public class ElmahMVCErrorFilter : IExceptionFilter
{
private static ErrorFilterConfiguration _config;
public void OnException(ExceptionContext context)
{
if (context.ExceptionHandled)
{
var e = context.Exception;
var context2 = context.HttpContext.ApplicationInstance.Context;
if ((context2 == null) || (!_RaiseErrorSignal(e, context2) && !_IsFiltered(e, context2)))
{
_LogException(e, context2);
}
}
}
private static bool _IsFiltered(System.Exception e, System.Web.HttpContext context)
{
if (_config == null)
{
_config = (context.GetSection("elmah/errorFilter") as ErrorFilterConfiguration) ?? new ErrorFilterConfiguration();
}
var context2 = new ErrorFilterModule.AssertionHelperContext((System.Exception)e, context);
return _config.Assertion.Test(context2);
}
private static void _LogException(System.Exception e, System.Web.HttpContext context)
{
ErrorLog.GetDefault((System.Web.HttpContext)context).Log(new Elmah.Error((System.Exception)e, (System.Web.HttpContext)context));
}
private static bool _RaiseErrorSignal(System.Exception e, System.Web.HttpContext context)
{
var signal = ErrorSignal.FromContext((System.Web.HttpContext)context);
if (signal == null)
{
return false;
}
signal.Raise((System.Exception)e, (System.Web.HttpContext)context);
return true;
}
}
现在,在您的过滤器配置中,您想要做这样的事情:
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new ElmahMVCErrorFilter());
}
请注意,我在那里留下了一条评论,提醒人们如果他们想添加一个全局过滤器来实际处理异常,它应该放在这个最后的过滤器之前,否则您将遇到未处理的异常被 ElmahMVCErrorFilter 忽略的情况,因为它尚未被处理,应该由 Elmah 模块进行日志记录,但是下一个过滤器标记异常已被处理,模块会忽略它,导致异常永远没有进入 elmah。
现在,请确保您 webconfig 中的 elmah 的 appsettings 看起来像这样:
<add key="elmah.mvc.disableHandler" value="false" /> <!
<add key="elmah.mvc.disableHandleErrorFilter" value="true" /> <!
<add key="elmah.mvc.requiresAuthentication" value="false" /> <!
<add key="elmah.mvc.allowedRoles" value="*" /> <!
<add key="elmah.mvc.route" value="errortracking" /> <!
这里重要的是"elmah.mvc.disableHandleErrorFilter",如果该值为false,它将使用elmah.mvc内部的处理程序来处理异常,而该处理程序将忽略您的customError设置。
这种设置允许您在类和视图中设置自己的ErrorHandler标签,同时仍通过ElmahMVCErrorFilter记录这些错误,通过在web.config中通过elmah模块添加自定义错误配置甚至编写自己的错误处理程序。您需要做的唯一一件事是记住不要在我们编写的elmah过滤器之前添加任何实际处理错误的过滤器。我忘了提到的是:elmah中不能有重复。