AtGetによる改善されたソリューションと、MVCルーティング内のelmahインターフェイスを処理するコントローラーを含むNuMAのELMAH.MVCパッケージが追加されました(そのaxdを使用する必要はありません)
。他のすべてのフィルターの最後で、すでに処理されたイベントをログに記録します。elmahモジュールは、アプリケーションによって処理されないその他のエラーのログを記録する必要があります。これにより、ヘルスモニターと、asp.netに追加できる他のすべてのモジュールを使用して、エラーイベントを確認することもできます。
そのソリューションの問題(およびここにあるすべてのもの) )何らかの方法でelmahエラーハンドラーが実際にエラーを処理しており、customErrorタグとして設定したり、ErrorHandlerや独自のエラーハンドラーを設定したりすることを無視している
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());
}
例外を実際に処理するグローバルフィルターを追加する場合、この最後のフィルターの前に移動する必要があることを人々に思い出させるためにコメントを残したことに注意してください。それは処理されておらず、Elmahモジュールによってログに記録される必要がありますが、次のフィルターは例外を処理済みとしてマークし、モジュールはそれを無視するため、例外がelmahになりません。
ここで、webconfigのelmahのappsettingsが次のようになっていることを確認します。
<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の場合、カスタムエラー設定を無視するデフォルトのHandleErrorHandlerを使用して実際に例外を処理するelmah.mvc内のハンドラーを使用します
この設定により、クラスとビューに独自のErrorHandlerタグを設定し、ElmahMVCErrorFilterを介してそれらのエラーを記録し、elmahモジュールを介してweb.configにcustomError設定を追加し、独自のエラーハンドラーを作成することもできます。あなたがしなければならない唯一のことは、私たちが書いたelmahフィルターの前に実際にエラーを処理するフィルターを追加しないことを忘れないでください。そして、私は言及するのを忘れていました:elmahに重複はありません。