Перейти к содержанию

Создание простого фильтра

Создадим самые примитивные фильтры — делающие некий вывод в консоль.

Фильтр определенного типа реализуется с помощью одного из пары — синхронного и асинхронного — интерфейсов:

  • фильтры авторизацииIAuthorizationFilter и IAsyncAuthorizationFilter;
  • фильтры ресурсовIResourceFilter и IAsyncResourceFilter;
  • фильтры действийIActionFilter и IAsyncActionFilter;
  • фильтры страницIPageFilter и IAsyncPageFilter;
  • фильтры исключенийIExceptionFilter и IAsyncExceptionFilter;
  • фильтры результатовIResultFilter и IAsyncResultFilter.

Обычно фильтры реализуются как атрибуты C#, что позволяет использовать их для декорирования контроллеров, действий и страниц Razor Pages.
Следует использовать один интерфейс из пары; если будут реализованы оба интерфейса, использоваться будет асинхронный.

Рассмотрим пример реализации IResourceFilter.

public class LogResourceFilter : Attribute, IResourceFilter
{
    public void OnResourceExecuting(ResourceExecutingContext context)
    {
        Console.WriteLine("Executing!");
    }
    public void OnResourceExecuted(ResourceExecutedContext context)
    {
        Console.WriteLine("Executed!");
    }
}

Метод OnResourceExecuting вызывается, когда запрос сначала достигает этапа обработки, на котором вызывается фильтр ресурсов. Метод OnResourceExecuted вызывается после выполнения остальной части конвейера1. Такие же методы есть и в интерфейсах других типов фильтров.

Информация, доступная на момент выполнения метода, содержится в аргументе: так, ResourceExecutingContext содержит объект HttpContext, сведения о маршруте, который выбрал это действие, детали действия и т.д. Для более поздних фильтров контексты будут содержать дополнительные подробности, такие как аргументы метода действия и ModelState. Для методов *Executed контекст также содержит информацию о том, как исполнялась остальная часть конвейера.

Асинхронная версия фильтра ресурсов требует реализации одного метода.

public class LogAsyncResourceFilter : Attribute, IAsyncResourceFilter
{
    public async Task OnResourceExecutionAsync(
        ResourceExecutingContext context,
        ResourceExecutionDelegate next)
    {
        Console.WriteLine("Executing async!");
        ResourceExecutedContext executedContext = await next();
        Console.WriteLine("Executed async!");
    }
}

Здесь вторым аргументом передается делегат, который нужно вызвать (асинхронно), чтобы выполнить оставшуюся часть конвейера.


  1. См. картинки здесь и здесь 


Последнее обновление : 3 мая 2023 г.
Дата создания : 3 октября 2022 г.

Комментарии

Комментарии