NuGet中现在有一个ELMAH.MVC软件包,其中包括Atif改进的解决方案以及一个控制器,该控制器处理MVC路由中的elmah接口(不再需要使用该axd)
该解决方案的问题(以及此处的所有解决方案) )是Elmah错误处理程序实际上以某种方式处理错误,而忽略了您可能要设置为customError标记或通过ErrorHandler或您自己的错误处理程序设置的内容
恕我直言,最好的解决方案是创建一个过滤器,该过滤器将在所有其他过滤器的末尾起作用,并记录已处理的事件。elmah模块应注意记录应用程序未处理的其他错误。这也将允许您使用运行状况监视器以及可以添加到asp.net的所有其他模块来查看错误事件。
我在elmah.mvc中的ErrorHandler上使用反射器编写了此外观
public class ElmahMVCErrorFilter : IExceptionFilter
{
private static ErrorFilterConfiguration _config;
public void OnException(ExceptionContext context)
{
if (context.ExceptionHandled) //The unhandled ones will be picked by the elmah module
{
var e = context.Exception;
var context2 = context.HttpContext.ApplicationInstance.Context;
//TODO: Add additional variables to context.HttpContext.Request.ServerVariables for both handled and unhandled exceptions
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)
{
//These filters should go at the end of the pipeline, add all error handlers before
filters.Add(new ElmahMVCErrorFilter());
}
请注意,我在此处留下了一条评论,以提醒人们,如果他们想添加一个将实际处理异常的全局过滤器,则应在最后一个过滤器之前进行处理,否则您将遇到ElmahMVCErrorFilter会忽略未处理的异常的情况,因为它尚未被处理,应该由Elmah模块记录下来,但是下一个过滤器会将异常标记为已处理,模块将忽略它,从而导致该异常永远不会变成elmah。
现在,确保您的webconfig中elmah的应用程序设置如下所示:
<add key="elmah.mvc.disableHandler" value="false" /> <!-- This handles elmah controller pages, if disabled elmah pages will not work -->
<add key="elmah.mvc.disableHandleErrorFilter" value="true" /> <!-- This uses the default filter for elmah, set to disabled to use our own -->
<add key="elmah.mvc.requiresAuthentication" value="false" /> <!-- Manages authentication for elmah pages -->
<add key="elmah.mvc.allowedRoles" value="*" /> <!-- Manages authentication for elmah pages -->
<add key="elmah.mvc.route" value="errortracking" /> <!-- Base route for elmah pages -->
这里重要的是“ elmah.mvc.disableHandleErrorFilter”,如果为false,它将使用elmah.mvc内部的处理程序,该处理程序将通过使用默认的HandleErrorHandler来实际处理异常,该处理程序将忽略您的customError设置
通过此设置,您可以在类和视图中设置自己的ErrorHandler标记,同时仍然通过ElmahMVCErrorFilter记录这些错误,甚至通过elmah模块将customError配置添加到web.config中,甚至编写自己的错误处理程序。您唯一需要做的就是记住,在我们编写的Elmah过滤器之前,不要添加任何将实际处理错误的过滤器。我忘了提:Elmah中没有重复品。