Ответ
В ASP.NET Core фильтры действий (Action Filters) позволяют выполнять код на разных этапах конвейера обработки запроса. Они реализуют интерфейсы из пространства имен Microsoft.AspNetCore.Mvc.Filters.
Основные типы фильтров:
- IActionFilter — выполняется непосредственно до (
OnActionExecuting) и после (OnActionExecuted) вызова метода действия. Идеален для логирования, валидации входных данных или изменения аргументов. - IAsyncActionFilter — асинхронная версия
IActionFilter. - IResultFilter — выполняется до (
OnResultExecuting) и после (OnResultExecuted) выполнения результата действия (например, рендеринга представления). Полезен для модификации HTTP-заголовков или результата. - IExceptionFilter — срабатывает при необработанном исключении в конвейере (
OnException). Используется для централизованной обработки ошибок. - 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, а то как будто про какую-то магию речь, а на деле всё просто, как три копейки.
Смотри, есть у тебя конвейер обработки запроса — этакий конвейер, куда запрос залетает, а вылетает уже ответ. Так вот фильтры действий — это такие хулиганы, которые виснут на этом конвейере в определённых местах и делают свою хуйню: логируют, проверяют права, ловят ошибки. Без них можно, но с ними — цивилизованно, блядь.
Какие они бывают, эти фильтры:
IActionFilter— классика жанра. Работает прямо перед вызовом твоего метода (OnActionExecuting) и сразу после (OnActionExecuted). Представь: вот ты заходишь в метод, а он тебе — «стой, пацан, я тебя сначала залогирую». А на выходе — «всё, иди, я ещё статус код проверю». Идеально для логирования или чтобы поковыряться в аргументах, которые пришли.IAsyncActionFilter— то же самое, но для асинхронных любителей. Чтоб не блокировать потоки, епта.IResultFilter— этот чувак включается до того, как твой результат (например, HTML страница) начнёт формироваться (OnResultExecuting), и после того, как всё уже отправилось клиенту (OnResultExecuted). Хочешь в последний момент заголовки поправить или статистику какую собрать — он твой бро.IExceptionFilter— спасатель, ёб твою мать. Если в твоём коде вылезет необработанная ошибка и все остальные фильтры разбегутся, этот выйдет и скажет: «Не паникуйте, я всё улажу» (OnException). Централизованная обработка ошибок — это про него.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] — это всё они, родные. Бери и пользуйся, нехуй городить своё, если не надо.
Вот и вся философия. Ничего сложного, просто удобные крючки, чтобы встроить свою логику в нужное место. Как прокладки в машине — стоят себе тихо, а без них уже не то.