Как предотвратить ошибки ведения журнала Elmah, обработанные в атрибуте Error
Я использую пакеты Elmah и Elmah.mvc в веб-приложении asp.net, mvc4. У меня есть конкретное действие контроллера, где я хочу обработать HttpAntiForgeryExceptions
определенным образом. Я создал собственный HandleErrorAttribute, который наследуется от HandleErrorAttribute
и реализует IExceptionFilter
,
При определенных обстоятельствах, с которыми я хочу справиться, я устанавливаю ExceptionContext.ExceptionHandled
к истине. Поведение, которое видит пользователь, является правильным, и ошибка обрабатывается так, как я хочу. Тем не менее, он также регистрирует ошибку в Elmah, чего я не хочу, так как я хотел бы сохранить журнал Elmah для истинных ошибок.
Аннотация контроллера выглядит так:
[ValidateAntiForgeryToken]
[CustomHandleAntiforgeryError]
public ActionResult ControllerMethod(Model model)
{
...
}
Ошибка CustomHandleAntiforgeryError выглядит следующим образом:
public class CustomHandleAntiforgeryErrorAttribute:
HandleErrorAttribute, IExceptionFilter
{
public override void OnException(ExceptionContext filterContext)
{
if (circumstancesAreOk)
{
filterContext.ExceptionHandled = true;
return;
}
}
}
Что еще мне нужно сделать, чтобы эта ошибка не регистрировалась в Elmah?
--- РЕДАКТИРОВАТЬ ---
Глядя на источник Elmah.MVC, атрибут HandleErrorAttribute регистрирует как обработанные, так и необработанные ошибки.
public override void OnException(ExceptionContext context)
{
base.OnException(context);
if (!context.ExceptionHandled) // if unhandled, will be logged anyhow
return;
var e = context.Exception;
var httpContext = context.HttpContext.ApplicationInstance.Context;
if (httpContext != null &&
(RaiseErrorSignal(e, httpContext) // prefer signaling, if possible
|| IsFiltered(e, httpContext))) // filtered?
return;
LogException(e, httpContext);
}
Я хотел бы, чтобы в моем настраиваемом атрибуте был сигнал Элме не регистрировать эту ошибку, и я был бы признателен за любые идеи.
2 ответа
См. ErrorFiltering из документации Elmah. Вот введение:
Когда ASP.NET сообщает ELMAH о необработанном исключении, приложение может решить, отклонить это исключение или нет. У приложения есть два способа сделать это, программно или декларативно через файл конфигурации. Более простой из них программный, потому что вам не нужно изучать что-то новое, кроме как написать обработчик событий на вашем любимом языке. Недостатком программного подхода является то, что вам нужно написать код и изменить свое веб-приложение (возможно, требующее статической перекомпиляции). С подходом, основанным на конфигурации, вы можете просто применить фильтрацию исключений к работающему приложению.
То, что я сделал, чтобы решить эту проблему, я считаю уродливым, но сработало для странного случая с фильтром ошибок, с которым я столкнулся. Я добавил пользовательский атрибут HandleErrorAttribute, скопировал его из Elmah HandleErrorAttribute и включил проверку нуля в методе OnException.
public override void OnException(ExceptionContext context)
{
base.OnException(context);
if (!context.ExceptionHandled) // if unhandled, will be logged anyhow
return;
string[] formKeys = context.HttpContext.Request.Form.AllKeys;
var e = context.Exception;
// linked to CustomErrorAttribute
if (e == null)
{
return;
}
bool test = HostingEnvironment.IsHosted;
var httpContext = context.HttpContext.ApplicationInstance.Context;
if (httpContext != null &&
(RaiseErrorSignal(e, httpContext) // prefer signaling, if possible
|| IsFiltered(e, httpContext))) // filtered?
return;
LogException(e, httpContext);
}
Затем в моем фильтре ошибок, который я не хотел инициировать обмен сообщениями с Elmah, а также установив для ExceptionContext ExceptionHandled значение true, я установил для Exception значение null.
public class MyCustomErrorFilter : IExceptionFilter
{
public void OnException(ExceptionContext filterContext)
{
if (blah, blah, blah, weird things but not something terrible)
{
filterContext.Exception = null;
filterContext.ExceptionHandled = true;
return;
}
}
}
Если бы это было чем-то более сложным и обычным явлением, я бы, вероятно, раскошелился с Elmah и посмотрел бы на создание пользовательской сборки Elmah, так как во многих ситуациях это выглядит немного странно.