ASP.NET MVC 4

ASP.NET MVC 4

Адам Фриман

Знакомство с контроллером

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

Подготовка нашего проекта

Чтобы подготовиться к этой главе, мы создали новый MVC проект, который называется ControllersAndActions, с помощью шаблона Empty. Мы выбрали шаблон Empty, потому что мы собираемся создавать все контроллеры и представления, которые нам нужны по мере продвижения по главе.

Совет

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

Создание контроллера при помощи IController

В MVC фреймворке классы контроллеров должны реализовывать интерфейс IController пространства имен System.Web.Mvc, как показано в листинге 15-1.

Листинг 15-1: Интерфейс System.Web.Mvc.IController
public interface IController
{
	void Execute(RequestContext requestContext);
}

Это очень простой интерфейс. Единственный метод, Execute, вызывается при запросе, который ориентирован на класс контроллера. MVC фреймворк знает, на какой класс был нацелен запрос, прочитав значение свойства controller, полученное от роутовых данных.

Вы можете выбрать для создания классов контроллеров реализацию IController, но это довольно низкоуровневый интерфейс, и вы должны проделать много работы, чтобы получить что-нибудь полезное. В листинге 15-2 показан простой контроллер BasicController, на основе которого представлена эта возможность.

Листинг 15-2: Класс BasicController
using System.Web.Mvc;
using System.Web.Routing;
namespace ControllersAndActions.Controllers
{
	public class BasicController : IController
	{
		public void Execute(RequestContext requestContext)
		{
			string controller = (string)requestContext.RouteData.Values["controller"];
			string action = (string)requestContext.RouteData.Values["action"];
			requestContext.HttpContext.Response.Write(
				string.Format("Controller: {0}, Action: {1}", controller, action));
		}
	}
}

Для создания этого класса мы щелкнули правой кнопкой мыши по папке Controllers проекта и выбрали Add -> New Class. Затем мы назвали наш контроллер BasicController и добавили код, показанный в листинге 15-2.

В нашем методе Execute мы читаем значения переменных controller и action из объекта RouteData, связанного с запросом, и записываем их в результат. Если вы запустите приложение и перейдите по /Basic/Index, вы увидите результат выполнения нашего контроллера, как показано на рисунке 15-1.

Рисунок 15-1: Результат, сгенерированный классом BasicController

Реализация интерфейса IController позволяет создать класс, который MVC распознает в качестве контроллера и которому отправляет запросы, но тут довольно трудно написать сложное приложение. MVC не определяет, как контроллер работает с запросами, что обозначает, что вы можете создать свой желаемый способ.

Совет

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

Создание контроллера путем наследования от класса Controller

MVC фреймворк бесконечно настраиваемый и расширяемый. Вы можете реализовать интерфейс IController для создания любого вида обработки запросов и генерации результата, который вам требуется. Не нравятся методы действий? Не важны отображаемые представления? Тогда вы можете просто взять дело в свои руки и написать лучший, более быстрый и более элегантный способ обработки запросов. Или же вы можете опираться на возможности, которые предоставила команда MVC, и это достигается наследованием ваших контроллеров от класса System.Web.Mvc.Controller.

System.Web.Mvc.Controller является классом, обеспечивающим поддержку обработки запросов, которая знакома большинству MVC разработчиков. Это то, что мы используем во всех наших примерах в предыдущих главах.

Класс Controller предоставляет три ключевые возможности:

  • Методы действия: Поведение контроллера разделено на множество методов (вместо того, чтобы иметь только один метод Execute()). Каждый метод действия срабатывает для определенного, «своего» URL и вызывается с параметрами, извлеченными из входящего запроса.
  • Результаты действия: Вы можете вернуть объект, описывая результат действия (например, отображение представления или перенаправление на другой URL или метод действия), который затем вы можете использовать по своему усмотрению. Разделение между указанием результатов и их выполнением упрощает модульное тестирование.
  • Фильтры: Вы можете инкапсулировать повторяющиеся виды поведения (например, аутентификацию, как вы видели в главе 11) в качестве фильтров, а затем добавлять каждый вид поведения в один или несколько контроллеров или методов действия, разместив [Attribute] в исходном коде.

Пока вам не нужно реализовывать очень конкретные требования, лучшим способом для создания контроллеров является наследование от класса Controller, и, как вы знаете, это то, что делает Visual Studio, когда создает новый класс в ответ на Add -> Controller. В листинге 15-3 показан простой контроллер, созданный таким образом. Мы назвали наш класс DerivedController.

Листинг 15-3: Простой контроллер, унаследованный от класса System.Web.Mvc.Controller
using System.Web.Mvc;
namespace ControllersAndActions.Controllers
{
	public class DerivedController : Controller
	{
		public ActionResult Index()
		{
			ViewBag.Message = "Hello from the DerivedController Index method";
			return View("MyView");
		}
	}
}

Базовый класс Controller реализует метод действия Execute и отвечает за вызов метода действия, имя которого соответствует значению action в роутовых данных.

Класс Controller также является нашей связью с системой представления Razor. В листинге мы возвращаем результат метода View, передавая имя представления, которое мы хотим отобразить, клиенту в качестве параметра. Листинг 15-4 показывает это представление MyView.cshtml, которое расположено в папке Views/Derived.

Листинг 15-4: Файл MyView.cshtml
@{
	ViewBag.Title = "MyView";
}
<h2>MyView</h2>
Message: @ViewBag.Message

Если вы запустите приложение и перейдете на /Derived/Index, будет выполнен метод действия, который мы определили, и будет отображено нужное представление, как показано на рисунке 15-2.

Рисунок 15-2: Результат, сгенерированный классом DerviedController

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

или RSS канал: Что новенького на smarly.net