9. В случае когда для действия определены атрибуты типа ActionFilterAttribute
, то выполнение действия может быть изменено таким атрибутом на следующих этапах: перед выполнением действия, после выполнения действия, перед исполнением результата или после исполнения результата действия.
10. В случае когда Actioninvoker
был специально переопределен, то после вызова действия результат действия передается методу CreateActionResult
свойства Actioninvoker
, который волен переопределить возвращаемый результат действия и вернуть результат типа ActionResult
.
11. В случае, когда Actioninvoker
не был переопределен, действие должно вернуть результат выполнения в виде ActionResult
.
12. Для результата типа ActionResult
вызывается метод ExecuteResult
, который осуществляет отображение результата для контекста запроса. Создав свой вариант класса, наследующий ActionResult
и реализующий ExecuteResult, можно переопределить действие и возвращать результат в нужном виде, например, формировать RSS-ленту.
Рассмотрим все шаги, относящиеся к контроллерам и действиям, более подробно. Для этого выделим основные темы:
□ фабрика контроллеров;
□ действия, фильтры и атрибуты;
□ механизм Model Binding.
После того как внутренний механизм MVC получит запрос, обработает таблицу маршрутизации и подберет необходимый маршрут, в дело вступает фабрика контроллеров. По умолчанию создается и используется экземпляр фабрики контроллеров типа DefaultFactoryController
. Для реализации своего варианта поведения фабрики контроллеров разработчик может реализовать свой класс, наследующий класс DefaultFactoryController
.
Фабрика контроллеров — это механизм, созданный с одной целью — создавать экземпляры контроллеров. В ASP.NET MVC фабрика контроллеров — это один из механизмов, который позволяет настроить поведение механизма MVC под себя, расширить функционал, предоставить разработчику возможность гибкой настройки действия MVC.
Фабрика контроллеров в ASP.NET реализует интерфейс IControllerFactory
, который содержит всего два метода:
public interface IControllerFactory {
IController CreateController(RequestContext requestContext,
string controllerName);
void ReleaseController(IController controller);
}
Здесь CreateController
должен создавать экземпляр контроллера, а ReleaseController
— разрушать его или проводить какие-то другие действия после завершения работы контроллера. Вы можете создать свою фабрику контроллеров, реализовав этот интерфейс. Но более простым способом расширения фабрики является ее реализация с помощью наследования от класса DefaultFactoryController
.
Для примера рассмотрим такую, вполне возможную задачу, решить которую позволит фабрика контроллеров:
□ необходимо создать механизм, который позволит ограничивать создание определенных контроллеров на основе "черного списка";
□ решение на базе маршрутов таблицы маршрутизации не может нас удовлетворить, поскольку создание маршрутов производится через исполняемый код, который по каким-то причинам не может быть модифицирован для загрузки маршрутов из внешнего источника;
□ решение на базе маршрутов не может нас удовлетворить в связи с тем, что у нас много универсальных маршрутов, которые затрагивают сразу много контроллеров;
□ требуется возможность работать с "черным списком" в виде редактирования определенного файла для возможности разделения и предоставления прав к нему.
Согласно этим требованиям создадим фабрику контроллеров, которая позволит нам ограничивать выполнение контроллеров по их именам через XML-файл "черного списка". Вот пример такого файла:
Как можно увидеть, данным файлом мы хотели бы заблокировать выполнение контроллеров AccountController
и AdminController
.
Реализуем фабрику контроллеров, наследуя класс DefaultFactoryController
:
public class ControllerFactory : DefaultControllerFactory {
protected override IController
GetControllerInstance(Type controllerType)
{
if (controllerType == null)
return base.GetControllerInstance(controllerType);
XmlDocument xdoc = new XmlDocument();
string blacklistPath =
HttpContext.Current.Server.MapPath("~/blacklist.xml");
xdoc.Load(blacklistPath);
XmlNodeList nodes = xdoc.GetElementsByTagName("blacklist");
foreach (XmlNode node in nodes[0].ChildNodes)
{
if (node.Attributes["typeName"].Value == controllerType.Name)
throw new HttpException(404, "Страница не найдена");
}
return base.GetControllerInstance(controllerType);
}
}
Как вы можете видеть, единственным методом нашего класса является реализация перегруженного метода GetControllerInstance
класса DefaultControllerFactory
. В нем мы реализуем следующую последовательность действий:
Читать дальше
Конец ознакомительного отрывка
Купить книгу