Чтение онлайн

на главную - закладки

Жанры

Шрифт:

Действия, фильтры и атрибуты

Переопределение свойства Actionlnvoker

После того как фабрика контроллеров создала контроллер, производится вызов его метода Execute, который с помощью специального свойства ActionInvoker определяет необходимый метод для выполнения действия и вызывает его. По умолчанию ActionInvoker создается как экземпляр класса ControllerActionInvoker, но разработчик волен переопределить его. Переопределение ActionInvoker — это

еще одна точка расширения ASP.NET MVC, которой вы можете воспользоваться для самых разнообразных целей. Например, т. к. именно ActionInvoker исполняет все необходимые фильтры типа ActionFilter, то вы вольны изменить этот механизм для того, чтобы часть фильтров не могла быть использована для ваших контроллеров в некотором гипотетическом случае.

По умолчанию метод InvokeAction класса ActionInvoker вместе с самим вызовом действия реализует механизм обработки заданных через атрибуты фильтров для действия.

Всего InvokeAction формирует четыре группы фильтров:

? ActionFilters — вызываются во время исполнения действия;

? ResultFilters — вызываются после исполнения действия при обработке результата;

? AuthorizationFilters — вызываются до исполнения действия, чтобы произвести проверку доступа;

? ExceptionFilters — вызываются во время обработки возникшего исключения.

Существуют такие действия, скорость вызова которых критически важна. В связи с этим лишние операции по поиску и исполнению фильтров типа ActionFilter могут отрицательно сказаться на производительности, даже когда никаких фильтров не используется. Поэтому создание своего варианта класса ActionInvoker и метода InvokeAction имеет смысл и может быть полезно. Вы можете реализовать InvokeAction в таком виде, в котором и производительность будет на высоте, и необходимый функционал не будет потерян.

Для примера рассмотрим листинг 4.2 с реализацией такого класса ActionInvoker, который максимально быстро вызывает действие контроллера без поддержки каких-либо атрибутов и накладных расходов на такую поддержку.

Листинг 4.2

public class FastControllerActionInvoker : ControllerActionInvoker

{

public override bool InvokeAction(

ControllerContext controllerContext, string actionName)

{

if (controllerContext == null)

throw new ArgumentNullException("controllerContext");

if (String.IsNullOrEmpty(actionName))

throw new ArgumentException("actionName");

ControllerDescriptor controllerDescriptor =

GetControllerDescriptor(controllerContext);

ActionDescriptor actionDescriptor = FindAction(controllerContext,

controllerDescriptor, actionName);

if (actionDescriptor != null)

{

IDictionary<string, object> parameters =

GetParameterValues(controllerContext, actionDescriptor);

var actionResult = InvokeActionMethod(controllerContext,

actionDescriptor, parameters);

InvokeActionResult(controllerContext, actionResult);

return true;

}

return false;

}

}

Существенное достоинство

этого класса в том, что уменьшение затрат на вызов действия позволило ускорить вызов в среднем на величину от 5 до 30 % по разным оценкам проведенного нами тестирования. С другой стороны, данный вариант не поддерживает многие стандартные механизмы MVC: фильтры, обработку ошибок, проверку авторизации.

Для использования нового класса FastControllerActionInvoker нужно присвоить его экземпляр свойству ActionInvoker необходимого контроллера. Например, используем наш новый класс для контроллера AccountController стандартного проекта MVC:

public AccountController

: this(null, null)

{

ActionInvoker = new FastControllerActionInvoker;

}

Атрибуты ActionMethodSelectorAttribute

Мы рассмотрели работу механизма ControllerActionInvoker, который призван найти и выполнить необходимое действие контроллера. Одной из особенностей этого поиска является поиск установленных для действий атрибутов типа ActionMethodSelectorAttribute. Эти атрибуты имеют одно-единственное предназначение — определение того, может ли быть вызвано это действие в данном контексте запроса или нет. Рассмотрим определение класса ActionMethodSelectorAttribute:

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false,

Inherited = true)]

public abstract class ActionMethodSelectorAttribute : Attribute {

public abstract bool IsValidForRequest(

ControllerContext controllerContext,

MethodInfo methodInfo);

}

Как вы видите, атрибут содержит только один метод IsValidForRequest, который возвращает булево значение, определяющее, может ли быть вызвано помеченное действие. Этот атрибут очень полезен для обеспечения безопасности, т. к. позволяет "спрятать" часть методов от любой возможности неправомерного использования.

Для удобства разработчиков MVC Framework уже реализует два атрибута, наследующих от ActionMethodSelectorAttribute:

? AcceptVerbsAttribute — позволяет задать для действия допустимые типы HTTP-запросов из следующего списка: GET, POST, PUT, DELETE, HEAD. Запросы, отличные от указанных, будут игнорироваться;

? NonActionAttribute — позволяет пометить метод, не являющийся действием. Такой метод невозможно будет вызвать никаким внешним запросом.

Используем эти атрибуты для нашего контроллера AdminController. Так как действия Index, Select и Delete могут быть вызваны только GET-запросами, пометим их соответствующим атрибутом, как показано в следующем фрагменте:

[AcceptVerbs(HttpVerbs.Get)]

public ActionResult Index

[AcceptVerbs(HttpVerbs.Get)]

public ActionResult Delete(Guid? userId)

[AcceptVerbs(HttpVerbs.Get)]

public ActionResult Select(Guid? userId)

Наоборот, действие Update вызывается только POST-запросами, поэтому пометим их следующим образом:

[AcceptVerbs(HttpVerbs.Post)]

public ActionResult Update(Guid? userId, string email,

Поделиться:
Популярные книги

Двадцать и двадцать один. Наивность

Das_Leben
Детективы:
триллеры
5.00
рейтинг книги
Двадцать и двадцать один. Наивность

Елизавета Петровна

Сахаров Андрей Николаевич
11. Романовы. Династия в романах
Проза:
историческая проза
5.50
рейтинг книги
Елизавета Петровна

Егерь. Вызов

Скиба Николай
3. Зверолов
Фантастика:
боевая фантастика
рпг
уся
фэнтези
попаданцы
6.00
рейтинг книги
Егерь. Вызов

Том 1. Романы. Рассказы. Критика

Газданов Гайто
1. Собрание сочинений в пяти томах
Проза:
русская классическая проза
5.00
рейтинг книги
Том 1. Романы. Рассказы. Критика

Война и мир. Первый вариант романа

Толстой Лев Николаевич
Проза:
русская классическая проза
5.25
рейтинг книги
Война и мир. Первый вариант романа

Волхв

Фаулз Джон Роберт
Проза:
современная проза
8.14
рейтинг книги
Волхв

В осаде

Кетлинская Вера Казимировна
Проза:
военная проза
советская классическая проза
5.00
рейтинг книги
В осаде

Всё о современной рыбалке. Полная энциклопедия

Горяйнов Алексей Георгиевич
Дом и Семья:
хобби и ремесла
5.00
рейтинг книги
Всё о современной рыбалке. Полная энциклопедия

Король планеты Зима (сборник)

Ле Гуин Урсула Кребер
9. Вся Ле Гуин
Фантастика:
фэнтези
8.42
рейтинг книги
Король планеты Зима (сборник)

Засеянные звезды. Сборник фантастических романов

Блиш Джеймс Бенджамин
13. «Клуб Любителей Фантастики»
Фантастика:
научная фантастика
6.25
рейтинг книги
Засеянные звезды. Сборник фантастических романов

Особый склад ума

Катценбах Джон
Детективы:
триллеры
7.33
рейтинг книги
Особый склад ума

Золушка (сборник)

Макбейн Эд
Мастера остросюжетного романа
Детективы:
полицейские детективы
5.00
рейтинг книги
Золушка (сборник)

Свет погасших звезд. Люди, которые всегда с нами

Раззаков Федор Ибатович
2. Свет погасших звезд
Документальная литература:
биографии и мемуары
5.00
рейтинг книги
Свет погасших звезд. Люди, которые всегда с нами

Бояръ-Аниме. Газлайтер. Том 32

Володин Григорий Григорьевич
32. История Телепата
Фантастика:
альтернативная история
аниме
фэнтези
попаданцы
6.40
рейтинг книги
Бояръ-Аниме. Газлайтер. Том 32