Учебный курс по ASP.NET MVC 3, глава 3. Модель выполнения приложения ASP.NET MVC

Это продолжение курса по разработки веб-приложений на базе фреймворка ASP.NET MVC 3, начало курса вы можете прочитать в статьях:

Основы выполнения приложения MVC

Запросы к приложению проходят через HTTP-модуль UrlRoutingModule, обрабатывающий запрос и отправляющий его по соответствующему маршруту. Этот модуль выбирает первый из маршрутов, удовлетворяющих запросу (объект маршрута – класс, реализующий RouteBase, и обычно является экземпляром класса Route). Если нет соответствующих маршрутов, объект UrlRoutingModule ничего не делает и отправляет запрос к ASP.NET или IIS.

Из выбранного объекта Route UrlRoutingModule получает объект, реализующий IrouteHandler и ассоциированный с объектом Route. Обычно в приложении MVC это экземпляр класса MvcRouteHandler. Экземпляр MvcRouteHandler создает объект MvcHandler, реализующий интерфейс IhttpHandler. Объект MvcHandler затем выбирает контроллер, который будет обрабатывать запрос. Подробнее см. ASP.NET Routing.

При запуске приложения под IIS 7.0 для проектов MVC отсутствует необходимость в расширениях файловых имен. Однако, в IIS 6.0 обработчик нуждается в том, чтобы вы связали расширение .mvc с ASP.NET ISAPI DLL.

Классы UrlRoutingModule и MvcRouteHandler – точки вхождения в фреймворк. Они выполняют следующие действия:

  • Выбор контроллера
  • Создание экземпляра контроллера
  • Вызов метода контроллера Execute

В следующей таблице приведен список этапов выполнения проекта MVC.

Этап

Информация

Приём запроса к приложению

В файле Global.asax в объект RouteRable добавляются объекты Route

Установка маршрутов

Модуль UrlRoutingModule использует первый соответствующий объект Route из коллекции RouteTable для создания объекта RouteData, который затем используется для создания объекта RequestContext.

Создание обработчика запроса MVC

Объект MvcRouteHandler создает экземпляр класса MvcHandler и передает экземпляр RequestContext в обработчик.

Создание контроллера

Объект MvcHandler использует экземпляр RequestContext для определения объекта \ IControllerFactory (обычно это экземпляр класса DefaultControllerFactory , с которым будет создан экземпляр контроллера.

Выполнение контроллера

Экземпляр MvcHandler вызывает метод контроллера Execute.

Вызов метода

Для контроллеров, наследуемых от класса ControllerBase определяется, какой метод контроллера необходимо вызвать, и этот метод вызывается.

Выполнение результата

Метод получает пользовательский ввод, подготавливает соответствующий ответ и выполняет результат, возвращая тип. Интегрированные типы результатов, которые могут быть выполнены, включают: ViewResult (генерирует представление, наиболее часто используемый тип), RedirectToRouteResult, RedirectResult, ContentResult, JsonResult, FileResult, EmptyResult.

Контроллеры и методы в приложениях ASP.NET MVC

Фреймворк MVC связывается URL-ы с классами-контроллерами. Контроллеры обрабатывают входящие запросы, пользовательский ввод, выполняют логику приложения. Класс контроллера обычно генерирует отдельный компонент представления.

Базовым классом к всем контроллерам является ControllerBase, предоставляющий базовую функциональность обработки. Класс Controller наследуется от ControllerBase и является стандартной реализацией контроллера, отвечает за::

  • Определение подходящего метода для вызова и валидация возможности его вызова
  • Получение значений для использования их в качестве аргументов методов
  • Обработка ошибок выполнения

Предоставление стандартного для генерации представлений класса WebFormViewEngine.

Для обеспечения безопасности доступ к контроллерам и методам можно использовать класс AuthorizeAttribute

Все классы контроллеров должны иметь суффикс “Controller”. Следующий пример иллюстрирует стадартный класс контроллера HomeController, содержающий методы для генерации представлений.

[HandleError]
public class HomeController : Controller
{
    public ActionResult Index()
    {
        ViewData["Message"] = "Welcome to ASP.NET MVC!";

        return View();
    }

    public ActionResult About()
    {
        return View();
    }
}

Действия (Action Methods)

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

Методы обычно связываются с пользовательским действием связью один-к-одному. Пример пользовательского действия: пользователь вводит URL в браузер, нажимает ссылку и отправляет форму. Каждое из этих действий отправляет запрос на сервер. В каждом случае URL запроса содержит информацию, которую фреймворк использует для вызова метода.

Когда вводится URL, приложение MVC использует правила маршрутизации, определенные в файле Global.asax, для обработки URL и определения пути контроллера. После этого контроллер определяет подходящий метод для обработки запроса. По умолчанию, URL запроса воспринимается как субпуть, включающий имя контроллера и имя метода. Например, если пользователь ввел URL https://contoso.com/MyWebSite/Products/Categories, субпуть будет /Products/Categories. Стандартное правило маршрутизации воспринимает Products как префикс имени контроллера, которое должно заканчиваться “Controller” (ProductsController). “Categories” воспринимается как имя метода. Поэтому правило маршрутизации вызывает метод Categories контроллера Products. Если URL выглядит как /Products/Detail/5, то в метод Detail передается в качестве параметра 5.

Пример метода HelloWorld:

public class MyController : Controller
{
    public ActionResult HelloWorld()
    {
        ViewData["Message"] = "Hello World!";
        return View();
    }
}

Возвращаемые типы результатов

Большинство методов возвращаются экземпляр класса, наследуемого от ActionResult, класса, являющегося базовым для всех результатов методо. Однако существуют другие типы результатов, которые можно использовать в зависимости от задачи метода. Например, самый популярный метод – вызов метода View. Метод View возвращает экземпляр класса ViewResult, наследуемый от ActionResult.

Вы можете создавать методы, возвращаемые объект любого типа (строку, число, булево). Эти типы будут обернуты в подходящий тип ActionResult перед тем, как будет сгенерированы в ответное действие.

В таблице перечислены интегрированные типы результатов и методы, которые возвращают их.

Action Result

Метод

Описание

ViewResult

View

Генерирует представление как веб-страницу.

PartialViewResult

PartialView

Генерирует частичное представление, определяемое часть представления, которая будет сгенерирована внутри другого представления.

RedirectResult

Redirect

Перенаправление на другой метод с указанием его URL.

RedirectToRouteResult

RedirectToAction

RedirectToRoute

Перенаправление на другой метод.

ContentResult

Content

Возвращение определенного пользователем типа контента.

JsonResult

Json

Возвращение сериализованного объекта JSON.

JavaScriptResult

JavaScript

Возвращение скрипта, выполняемого на стороне клиента.

FileResult

File

Возвращение бинарного потока.

EmptyResult

(None)

Возвращение результата в том случае, если метод возвращает null (void).

Определение публичных методов как Non-action

По умолчанию фреймворк MVC воспринимает все публичные методы как action методы. Если ваш класс контроллера содержит публичный метод и вы не хотите, чтобы он был так воспринят, вы должны определить его с атрибутом NonActionAttribute.

[NonAction]
private void DoSomething()
{
    // Method logic.
}

Параметры методов

По умолчанию значения для параметров методов получаются из коллекции данных запроса. Колекция данных содержит пары значений имя-значения. Класс контроллера определяет метод и значения в качестве его параметров, основываясь на экземпляре RouteData и данных из запроса. Если значение параметра не может быть обработано и тип параметра является ссылочным или nullable типом, в качестве значения параметра передается null. Иначе выбрасывается исключение.

Есть несколько путей доступа к параметрам в методах классов контроллеров. Класс Controller предоставляет Request и Response, которые имеют такой же смысл, как HttpRequest и HttpResponse , части ASP.NET. Однако эти объекты принимают объекты, реализующие абстрактные классы HttpRequestBase и HttpResponseBase. Эти базовые классы предоставляют возможность создания объектов-«болванок», что приводит к возможности эффективного и легкого тестирования классов контроллеров.

Пример того, как получить с помощью объекта Request строкове значение id:

public void Detail()
{
    int id = Convert.ToInt32(Request["id"]);
}

Автоматическое связывание параметров методов

Фреймворк MVC автоматически связывает значения параметров URL с параметрами методов и, по умолчанию, если метод принимает параметр, фреймворк осматривает входящие данные запроса и определяет, содержит ли запрос значение с подобным именем и, если да, то связывает.

Следующий пример показывает один из вариантов предыдущего примера, в котором параметр id связывается со значением запроса id. Из-за этого автоматического всязывания методу нет необходимости включать код для получения значения параметра из запроса.

public ResultAction Detail(int id)
{
    ViewData["DetailInfo"] = id;
    return View();
}

Можно также встроить значение параметра в URL как строку. Например, вместо /Products/Detail?id=3, можно использовать /Products/Detail/3. Стандартное правило маршрутизации имеет /{controller}/{action}/{id}.

Фреймворк MVC поддерживает опциональные аргументы для методов. Опциональные параметры обрабатываются с использованием аргументов типа nullable. Например, если метод принимает данные как часть строки запроса, но вы хотите, чтобы по умолчанию они были равны сегодняшней дате, вы можете использовать код из примера:

public ActionResult ShowArticles(DateTime? date)
{
    if(!date.HasValue)
    {
        date = DateTime.Now;
    }
    // ...
}

Если запрос включает значение для параметра date, то это значение будет передано в метод ShowArticles. Если запрос не содержит значения для этого параметра, то есть аргумент равен null, контроллер может предпринять необходимые действия для обработки этой ситуации.

Представления и рендеринг UI в приложениях ASP.NET MVC

ASP.NET MVC предлагает специальный механизм представлений для генерации внешнего вида страниц (UI). По умолчанию, MVC Framework может использовать типы ViewPage, ViewMasterPage и ViewUserControl наследуемые от существующей страницы aspx WebForms, мастер-страницы (*.master) и пользовательских элементов управления (*.ascx).

Другой подход – использование специального механизма представлений Razor, созданного специально для ASP.NET MVC, который позволяет значительно уменьшить количество кода необходимого для написания в представлениях. Сегодня, именно Razor рекомендуется и используется в MVC по умолчанию.

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

Генерация представлений

В паттерне MVC представления служат для логики пользовательских интерфейсов. Они не должны содержать код бизнес-логики или действий сб азой данных. Представление генерирует соответствующий пользовательский интерфейс, основываясь на данных, пришедших из метода контроллера.

Пример генерации представления в контроллере:

public ActionResult Categories()
{
    List<Category> categories = northwind.GetCategories();
    return View(categories);
}

В этом примере параметр, передающийся в метод View, является списком объектов Category. Метод View вызывает движок представления, использующий этот список для генерации представления и отображения его в браузере.

Благодарности

Благодарим Александра Белоцерковского за неоценимую помощь в подготовке данного курса.