Главная страница   /   9.1. Введение в маршрутизацию (ASP.NET MVC 4 в действии

ASP.NET MVC 4 в действии

ASP.NET MVC 4 в действии

Джеффри Палермо

9.1. Введение в маршрутизацию

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

Роуты по умолчанию

При создании нового приложения ASP.NET MVC, шаблон проекта по умолчанию создает метод под названием RegisterRoutes в файле Global.asax. Этот метод отвечает за настройку роутов для приложения и первоначально определяется с двумя роутами: роутом, который не следует проверять на соответствия (ignore route) и роутом по умолчанию, который сопоставим с {controller}/{action}/{id}, как показано здесь. api-роут тут опущен и рассматривается в главе 23.

Листинг 9-1: Роут по умолчанию
public static void RegisterRoutes(RouteCollection routes) {
	routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
	routes.MapRoute(
		"Default",
		"{controller}/{action}/{id}",
		new { controller = "Home", action = "Index",
			id = UrlParameter.Optional }
	);
}
protected void Application_Start()
{
	RegisterRoutes(RouteTable.Routes);
}

Строка 2: IgnoreRoute

Строка 4: Имя роута

Строка 5: URL с параметрами

Строки 6-7: Значения по умолчанию для параметров

Строка 12: Регистрация роутов при запуске приложения

Роуты определяются вызовом метода MapRoute, для которого существует несколько перегруженных вариантов. В данном случае роут по умолчанию настраивается вызовом перегруженного варианта, который принимает три аргумента. Первым является имя роута ("Default"). Второй – это шаблон URL, в соответствии с которым нужно создавать URL. Сейчас для него определены три сегмента - controller, action и id. Третий аргумент представляет собой анонимный тип, который определяет значения по умолчанию для этих сегментов. Давайте рассмотрим пример того, как может быть использован этот роут.

Если пользователь посетил URL-адрес http://example.com/users/edit/5, этот адрес соответствовал бы роуту по умолчанию, поскольку он имеет три сегмента, как показано на рисунке 9-1.

Рисунок 9-1: Как сегменты URL соотносятся с роутом

В этом случае строка users соотносится с параметром controller, edit соотносится с параметром action и 5 соотносится с параметром id. Так как это полностью соответствует нашему роуту, платформа MVC попытается найти класс UsersController и вызвать метод Edit, и передаст значение 5 в параметр id. Обратите внимание, что если контроллер или действие не могут быть найдены, платформа выведет ошибку 404.

Контроллер, который соответствует данному примеру, может быть определен следующим образом:

public class UsersController : Controller
{
	public ActionResult Edit(int id)
	{
		return View();
	}
}

По соглашению, платформа пытается соотнести параметры роута controller и action с классом и методом.

Параметры по умолчанию, добавленные к определению роута в листинге 9-1, означают, что URL не должен в точности совпадать с трехсегментным шаблоном URL. Если вы укажете Home как контроллер по умолчанию и Index как действие по умолчанию, и сегмент контроллера будет опущен, роутом по умолчанию станет HomeController. Аналогичным образом, если не указан сегмент действия, роут по умолчанию будет искать действие Index. Значение по умолчанию UrlParameter.Optional для параметра id означает, что роут может быть найден независимо от того, указан третий сегмент или нет. В таблице 9-1 показаны несколько примеров URL-адресов, которые могут соответствовать роуту по умолчанию. В дополнение к роуту по умолчанию, метод RegisterRoutes содержит вызов к IgnoreRoute.

Таблица 9-1: URL-адреса, которые соотносятся с роутом по умолчанию
URL Параметры роута Выбранный метод действия
http://example.com/Users/Edit/5 Controller = Users, Action = Edit, id = 5 UsersController.Edit(5)
http://example.com/Users/Edit Controller = Users, Action = Edit UsersController.Edit()
http://example.com/Users Controller = Users, Action = Index UsersController.Index()
http://example.com Controller = Home, Action = Index HomeController.Index()

Как и метод MapRoute, IgnoreRoute следует шаблону URL, но он также гарантирует, что любой URL-адрес, который соответствуют шаблону, не обрабатывается инфраструктурой маршрутизации. В этом случае шаблон {resource}.axd/{*pathInfo} гарантирует, что все URL, содержащие расширение файла .axd, не обрабатываются движком маршрутизации. Это необходимо, чтобы любые пользовательские обработчики HTTP (с расширением .axd) обрабатывались корректно и не перехватывались движком маршрутизации. Звездочка перед параметром pathInfo является универсальным (catch-all) параметром, который соответствует любой строке (включая слеши, которые обычно используются для установления границ сегментов URL). Мы рассмотрим catch-all роуты далее.

Такой тип маршрутизации, где URL сопоставляется с действием контроллера, известен как входящая маршрутизация, но есть и другой тип маршрутизации - исходящая маршрутизация, которая может генерировать URL из параметров роута, таких как контроллер и действие.

Входящая и исходящая маршрутизация

Инфраструктура маршрутизации разбивает URL на сегменты, исходя из логики приложения. Она должна владеть двумя направлениями:

  • Входящая маршрутизация - сопоставление запросов с контроллером, действием и любыми дополнительными параметрами (см. рисунок 9-2).
  • Исходящая маршрутизация - построение URL-адресов, которые соответствуют схеме URL из контроллера, действия и любых дополнительных параметров (см. рисунок 9-3).

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

Рисунок 9-2: Входящая маршрутизация принимает HTTP-запрос и соотносит части URL с контроллером и действием.

Исходящая маршрутизация, как показано на рисунке 9-3, описывает механизм генерации URL для ссылок и других элементов на сайте, где используются зарегистрированные роуты. Когда система маршрутизации выполняет обе эти задачи, схема URL может быть по-настоящему независимой от логики приложения. Если мы никогда не обходим схему URL при построении ссылок в представлении, ее довольно просто изменить независимо от логики приложения.

Рисунок 9-3: Исходящая маршрутизация генерирует соответствующие URL-адреса из заданного набора данных о роуте (обычно контроллера и действия).

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