Какие Action фильтры вы знаете в ASP.NET Core?

Ответ

В ASP.NET Core фильтры действий (Action Filters) позволяют выполнять код на разных этапах конвейера обработки запроса. Они реализуют интерфейсы из пространства имен Microsoft.AspNetCore.Mvc.Filters.

Основные типы фильтров:

  1. IActionFilter — выполняется непосредственно до (OnActionExecuting) и после (OnActionExecuted) вызова метода действия. Идеален для логирования, валидации входных данных или изменения аргументов.
  2. IAsyncActionFilter — асинхронная версия IActionFilter.
  3. IResultFilter — выполняется до (OnResultExecuting) и после (OnResultExecuted) выполнения результата действия (например, рендеринга представления). Полезен для модификации HTTP-заголовков или результата.
  4. IExceptionFilter — срабатывает при необработанном исключении в конвейере (OnException). Используется для централизованной обработки ошибок.
  5. IAuthorizationFilter — выполняется самым первым, до всех других фильтров, для проверки прав доступа (OnAuthorization).

Пример кастомного фильтра для логирования:

public class LoggingActionFilter : IActionFilter
{
    private readonly ILogger<LoggingActionFilter> _logger;

    public LoggingActionFilter(ILogger<LoggingActionFilter> logger)
    {
        _logger = logger;
    }

    public void OnActionExecuting(ActionExecutingContext context)
    {
        // Логируем начало выполнения
        _logger.LogInformation("Выполняется действие: {ActionName}", 
            context.ActionDescriptor.DisplayName);
    }

    public void OnActionExecuted(ActionExecutedContext context)
    {
        // Логируем завершение
        _logger.LogInformation("Действие {ActionName} завершено со статусом: {HttpStatusCode}",
            context.ActionDescriptor.DisplayName,
            context.HttpContext.Response.StatusCode);
    }
}

Применение фильтра:

Фильтры можно применять на разных уровнях:

  • На уровне действия:
    [ServiceFilter(typeof(LoggingActionFilter))]
    public IActionResult Get() { ... }
  • На уровне контроллера:
    [ServiceFilter(typeof(LoggingActionFilter))]
    public class HomeController : Controller { ... }
  • Глобально для всех действий: (регистрация в Program.cs)
    builder.Services.AddControllers(options =>
    {
        options.Filters.Add<LoggingActionFilter>();
    });

Встроенные фильтры: ASP.NET Core предоставляет готовые атрибуты, такие как [Authorize], [ValidateAntiForgeryToken], [RequireHttps] и [ResponseCache].

Ответ 18+ 🔞

Давай разберём эти ваши фильтры в ASP.NET Core, а то как будто про какую-то магию речь, а на деле всё просто, как три копейки.

Смотри, есть у тебя конвейер обработки запроса — этакий конвейер, куда запрос залетает, а вылетает уже ответ. Так вот фильтры действий — это такие хулиганы, которые виснут на этом конвейере в определённых местах и делают свою хуйню: логируют, проверяют права, ловят ошибки. Без них можно, но с ними — цивилизованно, блядь.

Какие они бывают, эти фильтры:

  1. IActionFilter — классика жанра. Работает прямо перед вызовом твоего метода (OnActionExecuting) и сразу после (OnActionExecuted). Представь: вот ты заходишь в метод, а он тебе — «стой, пацан, я тебя сначала залогирую». А на выходе — «всё, иди, я ещё статус код проверю». Идеально для логирования или чтобы поковыряться в аргументах, которые пришли.
  2. IAsyncActionFilter — то же самое, но для асинхронных любителей. Чтоб не блокировать потоки, епта.
  3. IResultFilter — этот чувак включается до того, как твой результат (например, HTML страница) начнёт формироваться (OnResultExecuting), и после того, как всё уже отправилось клиенту (OnResultExecuted). Хочешь в последний момент заголовки поправить или статистику какую собрать — он твой бро.
  4. IExceptionFilter — спасатель, ёб твою мать. Если в твоём коде вылезет необработанная ошибка и все остальные фильтры разбегутся, этот выйдет и скажет: «Не паникуйте, я всё улажу» (OnException). Централизованная обработка ошибок — это про него.
  5. IAuthorizationFilter — самый брутальный, сука. Он врывается первым, до всех остальных, и орёт: «А ты кто такой? Ты имеешь право тут быть?» (OnAuthorization). Если нет — сразу пиздык и до свидания. [Authorize] — это его родной брат.

Вот тебе живой пример фильтра, который логирует, что происходит:

public class LoggingActionFilter : IActionFilter
{
    private readonly ILogger<LoggingActionFilter> _logger;

    public LoggingActionFilter(ILogger<LoggingActionFilter> logger)
    {
        _logger = logger; // Подсунули логгер, красава
    }

    public void OnActionExecuting(ActionExecutingContext context)
    {
        // Ловим момент, когда действие вот-вот запустится
        _logger.LogInformation("Начинается выполнение действия: {ActionName}",
            context.ActionDescriptor.DisplayName);
    }

    public void OnActionExecuted(ActionExecutedContext context)
    {
        // Ловим момент, когда действие уже отработало
        _logger.LogInformation("Действие {ActionName} завершилось. Статус ответа: {HttpStatusCode}",
            context.ActionDescriptor.DisplayName,
            context.HttpContext.Response.StatusCode);
    }
}

Куда этот фильтр приткнуть? Да куда угодно, блядь:

  • На один конкретный метод (действие):
    [ServiceFilter(typeof(LoggingActionFilter))]
    public IActionResult Get() { ... }
  • На весь контроллер разом: (чтобы не плодить сущности)
    [ServiceFilter(typeof(LoggingActionFilter))]
    public class HomeController : Controller { ... }
  • Глобально, на ВСЁ приложение: (регистрируем в Program.cs, и пусть вся система логируется)
    builder.Services.AddControllers(options =>
    {
        options.Filters.Add<LoggingActionFilter>();
    });

А ещё, чувак, не изобретай велосипед. В ASP.NET Core уже есть куча готовых фильтров-атрибутов, которые решают типовые задачи. [Authorize], [ValidateAntiForgeryToken], [RequireHttps], [ResponseCache] — это всё они, родные. Бери и пользуйся, нехуй городить своё, если не надо.

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