NuGet에는 Atif의 개선 된 솔루션과 MVC 라우팅 내에서 elmah 인터페이스를 처리하는 컨트롤러 (더 이상 axd를 사용할 필요가 없음)를 포함하는 ELMAH.MVC 패키지가 있습니다.
해당 솔루션의 문제 (여기의 모든 문제 ) )는 elmah 오류 처리기가 실제로 오류를 처리하는 방법이며 customError 태그로 설정하거나 ErrorHandler 또는 자체 오류 처리기를 통해 설정하려는 것을 무시합니다.
최상의 솔루션 IMHO는 다른 모든 필터의 끝에서 작동하고 이미 처리 된 이벤트를 기록하는 필터를 만드는 것입니다. 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"입니다. 이것이 거짓 인 경우 elmah.mvc 내부의 핸들러를 사용하여 실제로는 handleErrorHandler를 사용하여 예외를 처리하는 customError 설정을 무시합니다.
이 설정을 사용하면 ElmahMVCErrorFilter를 통해 오류를 계속 기록하면서 elmah 모듈을 통해 web.config에 customError 구성을 추가하고 고유 한 Error Handler를 작성하여 클래스 및 뷰에서 고유 한 ErrorHandler 태그를 설정할 수 있습니다. 당신이해야 할 유일한 것은 우리가 작성한 elmah 필터 전에 실제로 오류를 처리하는 필터를 추가하지 않는 것입니다. 그리고 나는 언급하지 않았습니다 : elmah에는 중복이 없습니다.