← Назад к вопросам

Что такое фильтры?

2.0 Middle🔥 131 комментариев
#ASP.NET и Web API

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Что такое фильтры в ASP.NET Core?

Фильтры (Filters) в ASP.NET Core — это мощный механизм, позволяющий внедрять логику на разных этапах выполнения конвейера обработки HTTP-запроса, до и после вызова действия контроллера (или конечной точки в минимальных API). Они реализуют шаблон "сквозной функциональности" (cross-cutting concerns), так как позволяют централизованно управлять такими аспектами, как авторизация, валидация, обработка исключений, логирование и кэширование, без дублирования кода в каждом методе контроллера.


Типы фильтров и их порядок выполнения

Фильтры выполняются в строго определённом порядке, образуя конвейер фильтров (Filter Pipeline). В ASP.NET Core существует пять основных типов, перечисленных в порядке их выполнения:

1. Фильтры авторизации (Authorization Filters)

Выполняются первыми и определяют, авторизован ли пользователь для доступа к ресурсу. Если такой фильтр возвращает ошибку (например, через context.Result), дальнейшая обработка запроса прерывается. Пример использования: проверка ролей или политик доступа.

2. Фильтры ресурсов (Resource Filters)

Выполняются до и после остальных этапов конвейера (кроме авторизации). Позволяют реализовать логику, тесно связанную с жизненным циклом запроса, например, кэширование ответов или проверку токенов. Методы OnResourceExecuting и OnResourceExecuted.

3. Фильтры действий (Action Filters)

Самые часто используемые. Выполняются непосредственно до и после вызова метода действия контроллера (или обработчика конечной точки). Идеальны для:

  • Изменения аргументов, переданных в действие.
  • Изменения результата выполнения действия.
  • Логирования параметров запроса и ответа.

4. Фильтры исключений (Exception Filters)

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

5. Фильтры результатов (Result Filters)

Выполняются до и после выполнения конечного результата действия (например, ViewResult, JsonResult). Позволяют манипулировать результатом, например, добавлять заголовки в ответ или логировать формат результата.


Пример создания и применения фильтра действий

Самый простой способ — создать класс, реализующий интерфейс IActionFilter (или унаследоваться от ActionFilterAttribute):

using Microsoft.AspNetCore.Mvc.Filters;

// Кастомный фильтр действий для логирования
public class LogActionFilter : IActionFilter
{
    public void OnActionExecuting(ActionExecutingContext context)
    {
        // Выполняется ДО действия
        Console.WriteLine($"Action '{context.ActionDescriptor.DisplayName}' started at {DateTime.UtcNow}");
        Console.WriteLine($"Arguments: {string.Join(", ", context.ActionArguments)}");
    }

    public void OnActionExecuted(ActionExecutedContext context)
    {
        // Выполняется ПОСЛЕ действия
        Console.WriteLine($"Action '{context.ActionDescriptor.DisplayName}' completed at {DateTime.UtcNow}");
        if (context.Exception != null)
        {
            Console.WriteLine($"Exception: {context.Exception.Message}");
        }
    }
}

Применить фильтр можно несколькими способами:

  1. Глобально (на все контроллеры и действия):
// В Program.cs или Startup.cs
builder.Services.AddControllers(options =>
{
    options.Filters.Add<LogActionFilter>();
});
  1. На уровне контроллера:
[ApiController]
[Route("api/[controller]")]
[LogActionFilter] // Применяется ко всем действиям контроллера
public class ProductsController : ControllerBase
{
    [HttpGet]
    public IActionResult GetAll() => Ok(new[] { "Product1", "Product2" });
}
  1. На уровне отдельного действия:
public class ProductsController : ControllerBase
{
    [HttpGet("{id}")]
    [LogActionFilter] // Применяется только к этому действию
    public IActionResult GetById(int id) => Ok($"Product {id}");
}

Встроенные фильтры в ASP.NET Core

Платформа предоставляет множество готовых фильтров:

  • [Authorize] — фильтр авторизации.
  • [ValidateAntiForgeryToken] — проверка токенов от CSRF-атак.
  • [RequireHttps] — требование использования HTTPS.
  • [ResponseCache] — управление кэшированием ответов.
  • [TypeFilter(typeof(MyFilter))] или [ServiceFilter(typeof(MyFilter))] — внедрение зависимостей в фильтры.

Преимущества использования фильтров

  • Уменьшение дублирования кода: Логика, общая для нескольких действий, выносится в один фильтр.
  • Соблюдение принципа единственной ответственности: Контроллеры фокусируются на бизнес-логике, а сквозные задачи делегируются фильтрам.
  • Гибкость конфигурации: Фильтры можно применять на разных уровнях с разной областью видимости.
  • Упрощение тестирования: Фильтры изолированы и могут тестироваться отдельно от контроллеров.

Важные аспекты и лучшие практики

  1. Порядок выполнения: При наличии нескольких фильтров одного типа порядок задаётся явно через Order или зависит от области применения (глобальные, контроллер, действие).
  2. Внедрение зависимостей: Для использования сервисов из DI-контейнера в фильтрах применяйте ServiceFilter или TypeFilter.
  3. Производительность: Фильтры добавляют накладные расходы. Избегайте тяжёлых операций в часто используемых фильтрах (например, в каждом запросе).
  4. Асинхронные фильтры: Для асинхронных операций используйте интерфейсы IAsyncActionFilter, IAsyncResultFilter и т.д., чтобы не блокировать потоки.

Таким образом, фильтры — это фундаментальный инструмент в ASP.NET Core, обеспечивающий чистую архитектуру, поддержку сквозной функциональности и высокий уровень контроля над конвейером обработки запросов. Их грамотное применение значительно повышает качество и поддерживаемость backend-приложений.