Область действия фильтров

Последнее обновление: 09.04.2022

В ASP.NET Core MVC фильтры имеют три области действия:

  • Метод контроллера. Атрибут применяется к методу контроллера:

    public class HomeController : Controller
    {
        [SimpleResourceFilter]
        public IActionResult Index()
        {
            return View();
        }
    }
    
  • Область действия контроллер.

    Атрибут применяется к классу контроллера:

    [SimpleResourceFilter]
    public class HomeController : Controller
    {
        // содержимое контроллера
    }
    
  • Глобальная область действия, при которой фильтр применяется ко всем методам всех контроллеров приложения.

    Для определения фильтра как глобального надо при подключении соответствующих сервисов MVC добавить фильтр в коллекцию фильтров. Подключение глобально для всех сервисов MVC:

    var builder = WebApplication.CreateBuilder(args);
    builder.Services.AddMvc(options =>
    {
        options.Filters.Add(typeof(SimpleResourceFilter)); // подключение по типу
    
        // альтернативный вариант подключения
        options.Filters.Add(new SimpleResourceFilter()); // подключение по объекту
        options.Filters.Add<SimpleResourceFilter>();  // применение типизированного метода
    });
    

    Установка отдельно для контроллеров и представлений:

    var builder = WebApplication.CreateBuilder(args);
    builder.Services.AddControllersWithViews(options =>
    {
        options.Filters.Add(typeof(SimpleResourceFilter)); // подключение по типу
        options.Filters.Add(new SimpleResourceFilter()); // подключение по объекту
        options.Filters.Add<SimpleResourceFilter>(); 
    });
    

Кроме того, следует отметить, что есть определенная очередность выполнения фильтров в зависимости от области действия:

Очередность

Область действия

Метод фильтра

1

Глобальная

On[Stage]Executing

2

Контроллер

On[Stage]Executing

3

Действие контроллера

On[Stage]Executing

4

Действие контроллера

On[Stage]Executed

5

Контроллер

On[Stage]Executed

6

Глобальная

On[Stage]Executed

Например, создадим в проекте папку Filters и определим в ней три класса фильтров - GlobalResourceFilter, ControllerResourceFilter и ActionResourceFilter:

Область действия фильтров в ASP.NET Core MVC и C#

Класс GlobalResourceFilter будет выполнять роль глобального фильтра и будет иметь следующий код:

using Microsoft.AspNetCore.Mvc.Filters;

namespace MvcApp.Filters
{
    public class GlobalResourceFilter : Attribute, IResourceFilter
    {
        public void OnResourceExecuting(ResourceExecutingContext context)
        {
            Console.WriteLine("GlobalResourceFilter.OnResourceExecuting");
        }

        public void OnResourceExecuted(ResourceExecutedContext context)
        {
            Console.WriteLine("GlobalResourceFilter.OnResourceExecuted");
        }
    }
}

Класс ControllerResourceFilter будет фильтром на уровне контроллера и будет иметь следующий код:

using Microsoft.AspNetCore.Mvc.Filters;

namespace MvcApp.Filters
{
    public class ControllerResourceFilter : Attribute, IResourceFilter
    {
        public void OnResourceExecuting(ResourceExecutingContext context)
        {
            Console.WriteLine("ControllerResourceFilter.OnResourceExecuting");
        }

        public void OnResourceExecuted(ResourceExecutedContext context)
        {
            Console.WriteLine("ControllerResourceFilter.OnResourceExecuted");
        }
    }
}

Класс ActionResourceFilter будет выполнять роль фильтра на уровне отдельного действия контроллера и будет иметь следующий код:

using Microsoft.AspNetCore.Mvc.Filters;

namespace MvcApp.Filters
{
    public class ActionResourceFilter : Attribute, IResourceFilter
    {
        public void OnResourceExecuting(ResourceExecutingContext context)
        {
            Console.WriteLine("ActionResourceFilter.OnResourceExecuting");
        }

        public void OnResourceExecuted(ResourceExecutedContext context)
        {
            Console.WriteLine("ActionResourceFilter.OnResourceExecuted");
        }
    }
}

Изменим файл Program.cs для подключения классаGlobalResourceFilter в качестве глобального фильтра:

using MvcApp.Filters; // пространство имен фильтров

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllersWithViews(options => options.Filters.Add<GlobalResourceFilter>());

var app = builder.Build();
app.MapDefaultControllerRoute();

app.Run();

И определим следующий контроллер HomeController:

using Microsoft.AspNetCore.Mvc;
using MvcApp.Filters;  // пространство имен фильтров

namespace MvcApp.Controllers
{
    [ControllerResourceFilter]
    public class HomeController : Controller
    {
        [ActionResourceFilter]
        public IActionResult Index() => View();
    }
}

И после запуска приложения на консоли мы сможем наблюдать очередность выполнения фильтров:

Глобальные фильтры в ASP.NET Core MVC и C#

Переопределение порядка фильтров

ASP.NET Core MVC позволяет переопределить порядок выполнения фильтров. Для этого фильтр должен реализовать интерфейс IOrderedFilter, который определяет свойство Order - это свойство устанавливает порядок выполнения фильтра - чем оно меньше, тем раньше будет выполняться фильтр. Посмотрим на примере. Изменим класс ControllerResourceFilter следующим образом:

using Microsoft.AspNetCore.Mvc.Filters;

namespace MvcApp.Filters
{
    public class ControllerResourceFilter : Attribute, IResourceFilter, IOrderedFilter
    {
        public ControllerResourceFilter(int order) => Order = order;
        public int Order { get; }

        public void OnResourceExecuting(ResourceExecutingContext context)
        {
            Console.WriteLine("ControllerResourceFilter.OnResourceExecuting");
        }

        public void OnResourceExecuted(ResourceExecutedContext context)
        {
            Console.WriteLine("ControllerResourceFilter.OnResourceExecuted");
        }
    }
}

Теперь класс ControllerResourceFilter через конструктор устанавливает свойство Order.

И также изменим код контроллера:

using Microsoft.AspNetCore.Mvc;
using MvcApp.Filters;  // пространство имен фильтров

namespace MvcApp.Controllers
{
    [ControllerResourceFilter(int.MinValue)]
    public class HomeController : Controller
    {
        [ActionResourceFilter]
        public IActionResult Index() => View();
    }
}

Значение int.MinValue, которое передается через конструктор класса ControllerResourceFilter свойству Order, фактически означает, что этот фильтр будет запускаться раньше всех. В чем мы можем убедиться, запустив проект:

Поряд выполнения фильтров в ASP.NET Core MVC и C#
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850