Переопределение контроллеров

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

Как правило, для создания контроллера достаточно унаследовать свой класс от базового класса Controller. Однако если нам необходимо, чтобы наши контроллеры реализовали некоторую общую логику, мы можем определить свой базовый класс контроллера и уже от него наследовать остальные контроллеры. Либо мы также можем переопределить некоторые методы базового класса Controller, если они нас не устраивают.

Что мы можем в контроллере переопределить? В базовом классе Controller среди всех прочих методов есть три интересных метода:

[NonAction]
public virtual void OnActionExecuting(ActionExecutingContext context)
{
}
[NonAction]
public virtual void OnActionExecuted(ActionExecutedContext context)
{
}
[NonAction]
public virtual async Task OnActionExecutionAsync(ActionExecutingContext context,
            ActionExecutionDelegate next)
{
    if (context == null)
    {
        throw new ArgumentNullException(nameof(context));
    }

    if (next == null)
    {
        throw new ArgumentNullException(nameof(next));
    }

    OnActionExecuting(context);
    if (context.Result == null)
    {
        OnActionExecuted(await next());
    }
}

Его методы:

  • Метод OnActionExecuting() выполняется при вызове метода контроллера до его непосредственного выполнения. В качестве параметра принимает объект типа ActionExecutingContext, который имеет следующие свойства:

    • ActionArguments: объект типа IDictionary<string,object?>, который хранит передаваемые в метод аргументы и их значения (ключи в словаре представляют названия параметров метода)

    • ActionDescriptor: объект типа ActionDescriptor, который предоставляет информацию о выполняемом действии контроллера

    • Controller: предоставляет информацию о контроллере

    • Filters: представляет коллекцию фильтров, применяемых к действию контроллера

    • HttpContext: контекст запроса

    • ModelState: объект типа ModelStateDictionary, который хранит состояние модели

    • Result: объект типа IActionResult, который позволяет получить или установить результат действия контроллера

    • RouteData: представляет данные маршрута

  • Метод OnActionExecuted() выполняется после выполнения метода контроллера. В качестве параметра принимает объект типа ActionExecutedContext, который имеет следующие свойства:

    • ActionDescriptor: объект типа ActionDescriptor, который предоставляет информацию о выполняемом действии контроллера

    • Canceled: прерывает выполнение действия и фильтров действия

    • Controller: предоставляет информацию о контроллере

    • Exception: получает или устанавливает исключение

    • ExceptionDispatchInfo: получает или устанавливает объект ExceptionDispatchInfo с информацией об исключении

    • ExceptionHandled: указывает, обработано ли исключение

    • Filters: представляет коллекцию фильтров, применяемых к действию контроллера

    • HttpContext: контекст запроса

    • ModelState: объект типа ModelStateDictionary, который хранит состояние модели

    • Result: объект типа IActionResult, который позволяет получить или установить результат действия контроллера

    • RouteData: представляет данные маршрута

  • Метод OnActionExecutionAsync() представляет асинхронную версию метода OnActionExecuting().

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

Для решения этой задачи добавим в папку Controllers следующий класс контроллера:

using System.Linq;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;

public abstract class LogBaseController : Controller
{
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        Console.WriteLine($"Controller: {context.Controller.GetType().Name}");
        Console.WriteLine($"Action: {context.ActionDescriptor.DisplayName}");

        base.OnActionExecuting(context);
    }
}

В данном случае переопределяется метод OnActionExecuting(). В качестве параметра он принимает контекст выполнения метода - объект ActionExecutingContext, из которого мы можем получить самую различную информацию, в том числе и обратиться к контексту запроса.

В данном случае вначале получаем контроллер и выводим его имя на консоль приложения:

Console.WriteLine($"Controller: {context.Controller.GetType().Name}");

Свойство context.Controller позволяет получить информацию о текущем контроллере.

Далее получаем информацию о действии, которое обрабатывает запрос:

Console.WriteLine($"Action: {context.ActionDescriptor.DisplayName}");

Свойство context.ActionDescriptor представляет действие контроллера, в частности, его свойство DisplayName позволяет получить имя действия с учетом пространств имен и класса контроллера.

И теперь мы можем унаследовать контроллеры от нашего базового класса:

public class HomeController : LogBaseController
{
    public string Index() => "Hello METANIT.COM";
}

И теперь до начала работы метода Index будет срабатывать метод OnActionExecuting(), определенный в базовом классе LogBaseController, который выведет на консоль имя контроллера и его действия:

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