Фильтры в ASP.NET Core MVC. Фильтры исключений

Фильтры исключений позволяют обрабатывать не обработанные исключения. Для создания фильтра исключений необходимо реализовать один из двух интерфейсов — IExceptionFilter или IAsyncExceptionFilter. Рассмотрим работу с фильтрами исключений в приложении ASP.NET Core MVC.

Прежде, чем рассмотреть пример использования фильтра исключений, стоит немного вернуться назад и вспомнить схему работы фильтров в ASP.NET Core MVC

Схема работы фильтров ASP.NET Core MVC

Из этой схемы видно, что фильтры исключений обрабатывают не все исключения в приложении, а только те исключения, которые возникают при вызове действия контроллера в MVC. В частности, фильтры исключений способны обрабатывать исключения, которые возникают при создании объекта контроллера или при привязке модели, при выполнении фильтров действий или методов контроллера. При этом, фильтры исключений не обрабатывают исключения, возникающие в фильтрах ресурсов и в фильтрах результатов.

Пример фильтра исключений в ASP.NET Core MVC

Рассмотрим следующий код фильтра исключений:

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;

namespace AspExceptionFilter.Filters
{
    public class MyExceptionFilter : IExceptionFilter
    {
        ILogger<MyExceptionFilter> _logger;  
        public MyExceptionFilter(ILogger<MyExceptionFilter> logger) 
        { 
            _logger = logger;
        }

        public void OnException(ExceptionContext context)
        {
            _logger.LogCritical(context.Exception.Message);
            context.ExceptionHandled = true;
            context.Result = new ViewResult();
        }
    }
}

Первая особенность фильтров исключений в ASP.NET Core MVC заключается в том, что, в отличие от других фильтров, в фильтре исключений мы реализуем всего один метод — OnException или OnExceptionAsync (если мы хотим создать асинхронный фильтр). Этот метод содержит параметр ExceptionContext context в котором содержится исчерпывающая информация об исключении.  Для того, чтобы исключение считалось обработанным, мы устанавливаем для свойства ExceptionHandled  значение true:

context.ExceptionHandled = true;

после вывода информации об исключении в лог, мы, в качестве результата возвращаем объект ViewResult(). В результате этого, даже, если в контроллере произойдет какое-либо исключение, то мы об этом узнаем только из лога (что, в принципе, не хорошо, но для примера — сойдет).

Теперь создадим в каком-нибудь методе контроллера HomeController исключительную ситуацию:

public IActionResult Privacy(int value)
{
    double result = 10 / value;
    return View();
}

без использования фильтры мы бы увидели следующее необработанное исключение при попытке перейти на страницу Privacy():

Теперь воспользуемся нашим фильтром исключений. Во-первых, так как фильтр использует зависимость (ILogger), то зарегистрируем его как сервис:

    public static void Main(string[] args)
    {
        var builder = WebApplication.CreateBuilder(args);

        // Add services to the container.
        builder.Services.AddControllersWithViews();

        builder.Services.AddTransient<MyExceptionFilter>();

        //здесь стандартный код метода Main()
    }
}

Теперь применим фильтр к методу контроллера:

[ServiceFilter(typeof(MyExceptionFilter))]
public IActionResult Privacy(int value)
{
    double result = 10 / value;
    return View();
}

Теперь запустим приложение и попробуем перейти на страницу Privacy():

Как можно видеть на рисунке, наш фильтр исключений обработал исключение и вывел информацию в лог, а мы, как и ожидалось — перешли на страницу.

Итого

Фильтры исключений способны обрабатывать исключения, которые возникают при создании объекта контроллера или при привязке модели, при выполнении фильтров действий или методов контроллера. Для того, чтобы необработанное исключение считалось обработанным, необходимо установить для свойства ExceptionHandled контекста значение true.

Подписаться
Уведомить о
guest
0 Комментарий
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии