Зараз в NuGet існує пакет ELMAH.MVC, який включає вдосконалене рішення від Atif, а також контролер, який обробляє інтерфейс elmah в рамках маршрутизації MVC (більше не потрібно використовувати цей axd)
Проблема з цим рішенням (і з усіма тут ) полягає в тому, що так чи інакше обробник помилок elmah насправді обробляє помилку, ігноруючи те, що ви можете налаштувати як тег customError або через ErrorHandler або власний обробник помилок
Найкраще рішення IMHO - створити фільтр, який буде діяти в кінці всіх інших фільтрів і реєструвати події, які вже були оброблені. Модуль elmah повинен подбати про те, щоб зафіксувати інші помилки, які не обробляються програмою. Це також дозволить вам використовувати монітор здоров'я та всі інші модулі, які можна додати на asp.net, щоб переглянути події помилок
Я написав це, дивлячись відбивачем на ErrorHandler всередині elmah.mvc
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.
Тепер переконайтеся, що програми для 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
Ця настройка дозволяє встановлювати власні теги ErrorHandler у класах та представленнях, зберігаючи ці помилки за допомогою ElmahMVCErrorFilter, додаючи конфігурацію customError до вашого web.config через модуль elmah, навіть записуючи власні оброблювачі помилок. Єдине, що вам потрібно зробити, це пам’ятати, щоб не додавати жодних фільтрів, які б насправді обробляли помилку до фільтра elmah, про який ми писали. І я забув згадати: жодних дублікатів в ельмах.