Данное руководство устарело. Актуальное руководство: Руководство по ASP.NET Core 7
Фильтр ресурсов, как правило, применяется для переопределения результата действия. Это может быть полезно, например, в ситуации с кэшированием: в фильтре ресурсов можно получить кэш и сразу установить результат без ненужной повторной генерации результата в методах контроллера.
Для создания фильтра ресурсов надо реализовать либо интерфейс IResourceFilter, либо интерфейс IAsyncResourceFilter.
К примеру, пусть нам надо ограничить доступ к сайту для старых браузеров типа IE, и как раз для этого можно разработать простенький фильтр ресурсов. Для этого добавим в проект следующий класс фильтра:
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Filters; using System; using System.Text.RegularExpressions; namespace FiltersApp.Filters { public class IEFilterAttribute : Attribute, IResourceFilter { public void OnResourceExecuted(ResourceExecutedContext context) { } public void OnResourceExecuting(ResourceExecutingContext context) { // получаем информацию о браузере пользователя string userAgent = context.HttpContext.Request.Headers["User-Agent"].ToString(); if(Regex.IsMatch(userAgent, "MSIE|Trident")) { context.Result = new ContentResult { Content = "Ваш браузер устарел" }; } } } }
Интерфейс IResourceFilter предоставляет два метода:
OnResourceExecuting()
: срабатывает после фильтров авторизации, но до выполнения метода и работы фильтров действий, исключений и результатов
OnResourceExecuted()
: срабатывает после выполнения метода и фильтров действий, исключений и результатов
В качестве параметра в оба метода передается параметр типа ResourceExecutedContext, который позволяет получить данные запроса и управлять ответом.
В данном случае проверяем заголовок "User-Agent". Если он содержит соответствующие браузеру Internet Explorer подстроки, то с помощью свойства Result переустанавливаем ответ. И на этом обработка запроса завершается, и метод и последующие фильтры не выполняются.
Реализация той же задачи с помощью асинхронной версии:
using System; using System.Text.RegularExpressions; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Filters; namespace FiltersApp.Filters { public class IEAsyncFilterAttribute : Attribute, IAsyncResourceFilter { public async Task OnResourceExecutionAsync(ResourceExecutingContext context, ResourceExecutionDelegate next) { // получаем информацию о браузере пользователя string userAgent = context.HttpContext.Request.Headers["User-Agent"].ToString(); if (Regex.IsMatch(userAgent, "MSIE|Trident")) { context.Result = new ContentResult { Content = "Ваш браузер устарел" }; } else // если браузер не IE, передаем обаботку запроса дальше await next(); } } }
Асинхронная версия определяет только один метод, который принимает также паараметр ResourceExecutingContext. Второй парамет - объект ResourceExecutionDelegate предоставляет делегат, вызов которого позволяет передать обработку запроса дальше - следующим в конвейере фильтрам или непосредственно контроллеру или странице Razor Page.