Язык программирования C#9 и платформа .NET5 - Эндрю Троелсен
В следующей главе вы завершите построение веб-приложения ASP.NET Core, т.е. AutoLot.Mvc.
Глава 31
Создание приложений MVC с помощью ASP.NET Core
В главе 29 была заложена основа ASP.NET Core, а в главе 30 вы построили службу REST. В этой главе вы будете создавать веб-приложение с использованием паттерна МУС. Все начинается с помещения "V" обратно в "МУС".
На заметку! Исходный код, рассматриваемый в этой главе, находится в папке Chapter_31 внутри хранилища GitHub для настоящей книги. Вы также можете продолжить работу с решением, начатым в главе 29 и обновленным в главе 30.
Введение в представления ASP.NET Core
При построении служб ASP.NET Core были задействованы только части "М " (модели) и "С" (контроллеры ) паттерна МУС. Пользовательский интерфейс создается с применением части "V", т.е. представлений паттерна МУС. Представления строятся с использованием кода HTML, JavaScript, CSS и Razor. Они необязательно имеют страницу базовой компоновки и визуализируются из метода действия контроллера или компонента представления. Если вы имели дело с классической инфраструктурой ASP.NET МУС, то все должно выглядеть знакомым.
Экземпляры класса ViewResult и методы действий
Как кратко упоминалось в главе 29, объекты результатов ViewResult и PartialView являются экземплярами класса ActionResult, которые возвращаются из методов действий с применением вспомогательных методов класса Controller. Класс PartialViewResult спроектирован для визуализации внутри другого представления и не использует страницу компоновки, тогда как класс ViewResult обычно визуализируется в сочетании со страницей компоновки.
По соглашению, принятому в ASP.NET Core (что было и в ASP.NET МУС), экземпляр View или PartialView визуализирует файл *.cshtml с таким же именем, как у метода. Представление должно находиться либо в каталоге с именем контроллера (без суффикса Controller), либо в каталоге Shared (оба расположены внутри родительского каталога Views).
Например, следующий код будет визуализировать представление SampleAction.cshtml, находящееся в каталоге ViewsSample или ViewsShared:
[Route("[controller]/[action]")]
public class SampleController: Controller
{
public ActionResult SampleAction()
{
return View();
}
}
На заметку! Первым производится поиск в каталоге с именем контроллера. Если представление там не обнаружено, то поиск выполняется в каталоге Shared. Если оно по-прежнему не найдено, тогда генерируется исключение.
Чтобы визуализировать представление с именем, которое отличается от имени метода действия, передавайте имя файла (без расширения cshtml). Показанный ниже код будет визуализировать представление CustomViewName.cshtml:
public ActionResult SampleAction()
{
return View("CustomViewName");
}
Последние две перегруженные версии предназначены для передачи объекта данных, который становится моделью для представления. В первом примере применяется стандартное имя представления, а во втором указывается другое имя представления:
public ActionResult SampleAction()
{
var sampleModel = new SampleActionViewModel();
return View(sampleModel);
}
public ActionResult SampleAction()
{
var sampleModel = new SampleActionViewModel();
return View("CustomViewName",sampleModel);
}
В следующем разделе подробно рассматривается механизм визуализации Razor с использованием представления, которое визуализируется из метода действия по имени RazorSyntax() класса HomeController. Метод действия будет получать запись Car из экземпляра класса CarRepo, внедряемого в метод, и передавать экземпляр Car в качестве модели представлению.
Откройте HomeController в каталоге Controllers приложения AutoLot.Mvc и добавьте следующий оператор using:
using AutoLot.Dal.Repos.Interfaces;
Затем добавьте в контроллер метод Razorsyntax():
[HttpGet]
public IActionResult RazorSyntax([FromServices] ICarRepo carRepo)
{
var car = carRepo.Find(1);
return View(car);
}
Метод действия декорируется атрибутом HTTPGet с целью установки этого метода в качестве конечной точки приложения для /Home/RazorSyntax при условии, что поступивший запрос является HTTP-запросом GET. Атрибут FromServices на параметре ICarRepo информирует ASP.NET Core о том, что параметр не должен привязываться к каким-либо входящим данным, а взамен метод получает экземпляр реализации ICarRepo из контейнера DI (dependency injection — внедрение зависимостей). Метод получает экземпляр Car и возвращает экземпляр ViewResuit с применением метода View(). Поскольку имя представления не было указано, ASP.NET Core будет искать представление с именем RazorSyntax.cshtml в каталоге ViewsHome или ViewsShared. Если ни в одном местоположении представление не найдено, тогда клиенту (браузеру) возвратится исключение.
Запустите приложение и перейдите в браузере по ссылке https://localhost:5001/Home/RazorSyntax (в случае использования Visual Studio и IIS вам понадобится изменить номер порта). Так как в проекте отсутствует представление, которое может удовлетворить запрос, в браузер возвращается исключение. Вспомните из главы 29, что внутри метода Configure() класса Startup в конвейер HTTP добавляется вызов UseDeveloperExceptionPage(), если средой является Development. Результаты работы этого метода показаны на рис. 31.1.
Страница исключений для разработчиков предоставляет обширную информацию для отладки приложения, в числе которой низкоуровневые детали исключения, укомплектованные трассировкой стека. Теперь закомментируйте приведенную ниже строку в методе Configure() и замените ее "стандартным" обработчиком ошибок:
if (env.IsDevelopment())
{
// app.UseDeveloperExceptionPage();
app.UseExceptionHandler("/Home/Error");
...
}
Снова запустив приложение и перейдя по ссылке http://localhost:5001/Home/RazorSyntax, вы завидите стандартную страницу ошибок, которая показана на рис. 31.2.
На заметку! Во всех примерах URL в этой главе применяется веб-сервер Kestrel и порт 5001. Если вы имеете дело с Visual Studio и веб-сервером IIS Express, тогда используйте URL из профиля для IIS в файле launchsettings.json.
Стандартный обработчик ошибок выполняет перенаправление ошибок методу действия Error класса HomeController. Не забудьте восстановить применение страницы исключений для разработчиков в методе Configure():
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
...
}
Дополнительные сведения о настройке обработки ошибок и доступных вариантах ищите в документации по ссылке https://docs.microsoft.com/ru-ru/aspnet/core/fundamentals/error-handling.
Механизм визуализации и синтаксис Razor
Механизм визуализации Razor задумывался как усовершенствование механизма визуализации Web Forms и использует Razor в качестве основного языка. Razor — это код серверной стороны, который встраивается в представление, базируется на C# и избавляет от многих неудобств, присущих механизму визуализации