Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Примечание.
Это не последняя версия этой статьи. В актуальном релизе см. версию этой статьи для .NET 9.
Предупреждение
Эта версия ASP.NET Core больше не поддерживается. Дополнительные сведения см. в политике поддержки .NET и .NET Core. Для текущего выпуска см. версию .NET 9 этой статьи.
Внимание
Эта информация относится к предварительному выпуску продукта, который может быть существенно изменен до его коммерческого выпуска. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.
В текущем выпуске см. версию .NET 9 этой статьи.
Автор: Рик Андерсон (Rick Anderson)
В этом разделе вы внесете изменения в класс HelloWorldController
для использования файлов представления Razor. Это позволяет аккуратно инкапсулировать процесс создания HTML-ответов в клиент.
Шаблоны представлений создаются с помощью Razor. Шаблоны представлений на основе Razor:
- имеют расширение файла
.cshtml
; - Предоставьте элегантный способ создания HTML-выхода с помощью C#.
Сейчас метод Index
возвращает строку с сообщением в классе контроллера. В классе HelloWorldController
замените метод Index
следующим кодом:
public IActionResult Index()
{
return View();
}
Предыдущий код:
- вызывает метод View контроллера;
- использует шаблон представления для создания HTML-ответа.
Методы контроллера:
- называются методами действий; например, метод действия
Index
в предыдущем коде; - обычно возвращают IActionResult или класс, производный от ActionResult, а не тип, например
string
.
Добавить представление
Щелкните правой кнопкой мыши папку Views, а затем выберите Добавить > Новая папка. Назовите папку HelloWorld.
Щелкните правой кнопкой мыши папку Views/HelloWorld, а затем выберите Добавить > Новый элемент.
В диалоговом окне "Добавить новый элемент ", если доступен параметр "Показать все шаблоны ", выберите его.
В диалоговом окне Добавление нового элемента MvcMovie выполните следующие действия.
- В поле поиска в правом верхнем углу введите view
- Выберите Вид Razor — Пусто
- Сохраните значение поля "Имя",
Index.cshtml
. - Выберите Добавить
Замените содержимое файла представления Views/HelloWorld/Index.cshtml
Razor следующим.
@{
ViewData["Title"] = "Index";
}
<h2>Index</h2>
<p>Hello from our View Template!</p>
Перейдите к https://localhost:{PORT}/HelloWorld
:
Метод
Index
вHelloWorldController
выполнил операторreturn View();
, который указал, что метод должен использовать файл шаблона представления для отображения ответа в браузере.Имя файла шаблона представления не указано, MVC по умолчанию использует файл представления по умолчанию. Если имя файла представления не указано, возвращается представление по умолчанию. В этом примере представление по умолчанию имеет то же имя, что и метод действия
Index
. Используется шаблон/Views/HelloWorld/Index.cshtml
представления.На изображении ниже показана строка "Hello from our View Template!", которая жестко задана в представлении:
Изменение представлений и страниц макета
Выберите ссылки в меню (MvcMovie, Home и Privacy). Меню на каждой странице имеют одинаковый макет. Макет меню реализуется в Views/Shared/_Layout.cshtml
файле.
Откройте файл Views/Shared/_Layout.cshtml
.
Шаблоны макета позволяют:
- указать макет контейнера HTML сайта в одном месте;
- применение макета контейнера HTML на нескольких страницах сайта.
Найдите строку @RenderBody()
.
RenderBody
— это заполнитель, в котором отображаются все создаваемые страницы для определенных представлений, упакованные на странице макета. Например, если щелкнуть ссылку Privacy, представление Views/Home/Privacy.cshtml
отобразится в методе RenderBody
.
Изменение заголовка, нижнего колонтитула и ссылки меню в файле макета
Замените содержимое файла Views/Shared/_Layout.cshtml
следующей разметкой: Изменения выделены:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - Movie App</title>
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
<link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
<link rel="stylesheet" href="~/MvcMovie.styles.css" asp-append-version="true" />
</head>
<body>
<header>
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
<div class="container-fluid">
<a class="navbar-brand" asp-area="" asp-controller="Movies" asp-action="Index">Movie App</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
<ul class="navbar-nav flex-grow-1">
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">Home</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
</li>
</ul>
</div>
</div>
</nav>
</header>
<div class="container">
<main role="main" class="pb-3">
@RenderBody()
</main>
</div>
<footer class="border-top footer text-muted">
<div class="container">
© 2025 - Movie App - <a asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
</div>
</footer>
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
@await RenderSectionAsync("Scripts", required: false)
</body>
</html>
Приведенная выше разметка вносит следующие изменения:
- замена трех случаев
MvcMovie
наMovie App
. - Замена элемента привязки
<a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">MvcMovie</a>
на<a class="navbar-brand" asp-controller="Movies" asp-action="Index">Movie App</a>
.
В приведенной выше разметке asp-area=""
и значение атрибута были опущены, так как это приложение не использует области (Areas).
Примечание. Контроллер Movies
не был реализован. На этом этапе ссылка Movie App
не работает.
Сохраните изменения и щелкните ссылку Privacy. Обратите внимание, что заголовок вкладки браузера отображает Privacy Политика — Приложение Movie вместо Privacy Политика — MvcMovie.
Выберите ссылку Home.
Обратите внимание, что в заголовке и тексте привязки также отображается Movie App. Внеся одно изменение в шаблон макета, мы изменили заголовок и текст ссылки на всех страницах сайта.
Просмотрите файл Views/_ViewStart.cshtml
.
@{
Layout = "_Layout";
}
Файл Views/_ViewStart.cshtml
подключает файл Views/Shared/_Layout.cshtml
к каждому представлению. Свойство Layout
может использоваться для задания другого представления макета или установки значения null
, чтобы макетный файл не использовался.
Откройте файл представления Views/HelloWorld/Index.cshtml
.
Измените заголовок и элемент <h2>
, как выделено ниже:
@{
ViewData["Title"] = "Movie List";
}
<h2>My Movie List</h2>
<p>Hello from our View Template!</p>
Заголовок и элемент <h2>
немного отличаются, чтобы вы видели, какой именно фрагмент кода изменяет отображение.
ViewData["Title"] = "Movie List";
в приведенном выше коде присваивает свойству Title
словаря ViewData
значение "Movie List". Свойство Title
используется в элементе HTML <title>
на странице макета:
<title>@ViewData["Title"] - Movie App</title>
Сохраните изменения и перейдите к https://localhost:{PORT}/HelloWorld
.
Обратите внимание, что были изменены следующие элементы:
- Заголовок браузера.
- Основной заголовок.
- Дополнительные заголовки.
Если в браузере изменения не отображаются, это может означать, что содержимое кэшировано. В этом случае нажмите в браузере клавиши CTRL+F5 для принудительной загрузки ответа сервера. Заголовок браузера создается с помощью атрибута ViewData["Title"]
, который задается в шаблоне представления Index.cshtml
и дополнительной строки "- Movie App", добавляемой в файл макета.
Содержимое Index.cshtml
шаблона представления объединяется с шаблоном Views/Shared/_Layout.cshtml
представления. В браузер отправляется один HTML-ответ. Шаблоны макетов позволяют легко вносить изменения, применяемые ко всем страницам в приложении. Дополнительные сведения см. в разделе Макет.
Небольшой фрагмент данных (сообщение "Hello from our View Template!") все равно жестко задан в коде. Приложение MVC имеет «V» (представление), «C» (контроллер), но пока не имеет «M» (модель).
Передача данных из контроллера в представление
Действия контроллера вызываются в ответ на входящий запрос URL-адреса. Код, обрабатывающий входящие запросы браузера, добавляется в класс контроллера. Контроллер извлекает данные из источника данных и определяет тип ответа, который будет отправлен в браузер. Контроллер может использовать шаблоны представлений для создания и форматирования ответа HTML, отправляемого браузеру.
Контроллер отвечает за предоставление данных, необходимых шаблону представления для отображения ответа.
Шаблоны представлений недолжны:
- выполнять бизнес-логику;
- непосредственно взаимодействовать с базой данных.
Шаблон представления должен работать только с данными, которые предоставляет ему контроллер. Поддержание данного "разделения ответственности" помогает поддерживать код:
- Чистый
- тестируемый
- поддерживаемый.
Сейчас метод Welcome
в классе HelloWorldController
принимает параметры name
и ID
, после чего выводит значения напрямую в браузер.
Вместо отображения ответа в виде строки настройте контроллер для использования шаблона представления. Шаблон представления создает динамический ответ, для получения которого необходимо передать соответствующие данные из контроллера в представление. Для этого контроллер может поместить динамические данные (параметры), которые требуются шаблону представления, в словарь ViewData
, Шаблон просмотра может получить доступ к динамическим данным.
В HelloWorldController.cs
измените метод Welcome
, чтобы добавить значения Message
и NumTimes
в словарь ViewData
.
Словарь ViewData
представляет собой динамический объект, а это означает, что можно использовать любой тип. Объект ViewData
не имеет определенных свойств, пока не будет добавлен какой-либо элемент.
Система привязки модели MVC автоматически сопоставляет именованные параметры name
и numTimes
из строки запроса с параметрами метода. Полный HelloWorldController
:
using Microsoft.AspNetCore.Mvc;
using System.Text.Encodings.Web;
namespace MvcMovie.Controllers;
public class HelloWorldController : Controller
{
public IActionResult Index()
{
return View();
}
public IActionResult Welcome(string name, int numTimes = 1)
{
ViewData["Message"] = "Hello " + name;
ViewData["NumTimes"] = numTimes;
return View();
}
}
Объект словаря ViewData
содержит данные, которые будут передаваться в представление.
Создайте шаблон представления приветствия с именем Views/HelloWorld/Welcome.cshtml
.
В шаблоне представления Welcome.cshtml
создайте цикл, который будет отображать строку "Hello" NumTimes
. Замените все содержимое Views/HelloWorld/Welcome.cshtml
следующим:
@{
ViewData["Title"] = "Welcome";
}
<h2>Welcome</h2>
<ul>
@for (int i = 0; i < (int)ViewData["NumTimes"]!; i++)
{
<li>@ViewData["Message"]</li>
}
</ul>
Сохраните изменения и перейдите по следующему URL-адресу:
https://localhost:{PORT}/HelloWorld/Welcome?name=Rick&numtimes=4
Данные извлекаются по URL-адресу и передаются в контроллер с помощью средства привязки модели MVC. Контроллер упаковывает данные в словарь ViewData
и передает этот объект в представление. Представление отображает данные в формате HTML в браузере.
В примере выше мы использовали словарь ViewData
для передачи данных из контроллера в представление. Далее в этом руководстве для передачи данных из контроллера в представление мы будем использовать модель представления. Подход к передаче данных на основе модели представления является предпочтительным относительно применения словаря ViewData
.
В следующем руководстве создается база данных фильмов.
В этом разделе вы внесете изменения в класс HelloWorldController
для использования файлов представления Razor. Это чётко инкапсулирует процесс создания HTML-ответов для клиента.
Шаблоны представлений создаются с помощью Razor. Шаблоны представлений на основе Razor:
- имеют расширение файла
.cshtml
; - Предоставьте элегантный способ создания HTML-выходных данных на C#.
Сейчас метод Index
возвращает строку с сообщением в классе контроллера. В классе HelloWorldController
замените метод Index
следующим кодом:
public IActionResult Index()
{
return View();
}
Предыдущий код:
- вызывает метод View контроллера;
- использует шаблон представления для создания HTML-ответа.
Методы контроллера:
- называются методами действий; например, метод действия
Index
в предыдущем коде; - обычно возвращают IActionResult или класс, производный от ActionResult, а не тип, например
string
.
Добавить представление
Щелкните правой кнопкой мыши папку Views, а затем выберите Добавить > Новая папка. Назовите папку HelloWorld.
Щелкните правой кнопкой мыши папку Views/HelloWorld, а затем выберите Добавить > Новый элемент.
В диалоговом окне "Добавить новый элемент" выберите "Показать все шаблоны".
В диалоговом окне Добавление нового элемента MvcMovie выполните следующие действия.
- В поле поиска в правом верхнем углу введите view
- Выберите Представление Razor — пустое
- Сохраните значение поля Имя,
Index.cshtml
. - Выберите Добавить
Замените содержимое файла представления Views/HelloWorld/Index.cshtml
Razor следующим.
@{
ViewData["Title"] = "Index";
}
<h2>Index</h2>
<p>Hello from our View Template!</p>
Перейдите к https://localhost:{PORT}/HelloWorld
:
Метод
Index
вHelloWorldController
выполнил операторreturn View();
, который указал, что метод должен использовать шаблонный файл представления для формирования ответа в браузере.Имя файла шаблона представления не указано, MVC по умолчанию использует файл представления по умолчанию. Если имя файла представления не указано, возвращается представление по умолчанию. В этом примере представление по умолчанию имеет то же имя, что и метод действия
Index
. Шаблон представления/Views/HelloWorld/Index.cshtml
используется.На изображении ниже показана строка "Hello from our View Template!", которая вписана вручную в представлении.
Изменение вида и макета страниц
Выберите ссылки в меню (MvcMovie, Home и Privacy). Меню на каждой странице имеют одинаковый макет. Макет меню реализуется в Views/Shared/_Layout.cshtml
файле.
Откройте файл Views/Shared/_Layout.cshtml
.
Шаблоны макета позволяют:
- Указать расположение контейнера HTML сайта в одном месте.
- Применение макета контейнера HTML на нескольких страницах сайта.
Найдите строку @RenderBody()
.
RenderBody
является заполнителем, где отображаются все создаваемые страницы для определенных представлений, встроенные в страницу макета. Например, если щелкнуть ссылку Privacy, представление Views/Home/Privacy.cshtml
отобразится в методе RenderBody
.
Изменение заголовка, нижнего колонтитула и ссылки меню в файле макета
Замените содержимое файла Views/Shared/_Layout.cshtml
следующей разметкой: Изменения выделены:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - Movie App</title>
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
<link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
</head>
<body>
<header>
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
<div class="container-fluid">
<a class="navbar-brand" asp-area="" asp-controller="Movies" asp-action="Index">Movie App</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
<ul class="navbar-nav flex-grow-1">
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">Home</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
</li>
</ul>
</div>
</div>
</nav>
</header>
<div class="container">
<main role="main" class="pb-3">
@RenderBody()
</main>
</div>
<footer class="border-top footer text-muted">
<div class="container">
© 2023 - Movie App - <a asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
</div>
</footer>
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
@await RenderSectionAsync("Scripts", required: false)
</body>
</html>
Приведенная выше разметка вносит следующие изменения:
- Замена трёх вхождений
MvcMovie
наMovie App
. - Замена элемента привязки
<a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">MvcMovie</a>
на<a class="navbar-brand" asp-controller="Movies" asp-action="Index">Movie App</a>
.
В приведенной выше разметке asp-area=""
вспомогательный объект для тегов привязки и значение атрибута были опущены, так как это приложение не использует Areas.
Примечание. Контроллер Movies
не был реализован. На этом этапе ссылка Movie App
не работает.
Сохраните изменения и щелкните ссылку Privacy. Обратите внимание, что заголовок вкладки браузера отображает Privacy Политика — Приложение Movie вместо Privacy Политика — MvcMovie.
Выберите ссылку Home.
Обратите внимание, что в заголовке и тексте привязки также отображается Movie App. Внеся одно изменение в шаблон макета, мы изменили заголовок и текст ссылки на всех страницах сайта.
Просмотрите файл Views/_ViewStart.cshtml
.
@{
Layout = "_Layout";
}
Файл Views/_ViewStart.cshtml
подключает файл Views/Shared/_Layout.cshtml
к каждому представлению. Свойство Layout
можно использовать, чтобы установить другое представление макета или задать значение null
, чтобы не использовался файл макета.
Откройте файл представления Views/HelloWorld/Index.cshtml
.
Измените заголовок и элемент <h2>
, как выделено ниже:
@{
ViewData["Title"] = "Movie List";
}
<h2>My Movie List</h2>
<p>Hello from our View Template!</p>
Заголовок и элемент <h2>
немного отличаются, чтобы вы видели, какой именно фрагмент кода изменяет отображение.
ViewData["Title"] = "Movie List";
в приведенном выше коде присваивает свойству Title
словаря ViewData
значение "Movie List". Свойство Title
используется в элементе HTML <title>
на странице макета:
<title>@ViewData["Title"] - Movie App</title>
Сохраните изменения и перейдите к https://localhost:{PORT}/HelloWorld
.
Обратите внимание, что были изменены следующие элементы:
- Заголовок браузера.
- Основной заголовок.
- Дополнительные заголовки.
Если в браузере изменения не отображаются, это может означать, что содержимое кэшировано. В этом случае нажмите в браузере клавиши CTRL+F5 для принудительной загрузки ответа сервера. Заголовок браузера создается с помощью атрибута ViewData["Title"]
, который задается в шаблоне представления Index.cshtml
и дополнительной строки "- Movie App", добавляемой в файл макета.
Содержимое Index.cshtml
шаблона представления объединяется с шаблоном Views/Shared/_Layout.cshtml
представления. В браузер отправляется один HTML-ответ. Шаблоны макетов позволяют легко вносить изменения, применяемые ко всем страницам в приложении. Дополнительные сведения см. в разделе Макет.
Небольшой фрагмент данных (сообщение "Hello from our View Template!") все равно жестко задан в коде. В приложении MVC есть "V" (представление) и "C" (контроллер), но пока нет "M" (модели).
Передача данных из контроллера в представление
Действия контроллера вызываются в ответ на входящий запрос URL-адреса. Код, обрабатывающий входящие запросы браузера, добавляется в класс контроллера. Контроллер извлекает данные из источника данных и определяет тип ответа, который будет отправлен в браузер. Контроллер может использовать шаблоны представлений для создания и форматирования ответа HTML, отправляемого браузеру.
Контроллер отвечает за предоставление данных, необходимых шаблону представления для отображения ответа.
Шаблоны представлений недолжны:
- выполнять бизнес-логику;
- непосредственно взаимодействовать с базой данных.
Вместо этого они должны работать только с данными, которые им предоставляет контроллер. Подобное разделение сфер ответственности позволяет обеспечить максимальную оптимизацию кода, а также удобство его
- чистый
- тестируемый
- поддерживаемый
Сейчас метод Welcome
в классе HelloWorldController
принимает параметры name
и ID
, после чего выводит значения напрямую в браузер.
Вместо отображения ответа в виде строки настройте контроллер для использования шаблона представления. Шаблон представления создает динамический ответ, для получения которого необходимо передать соответствующие данные из контроллера в представление. Для этого контроллер может поместить динамические данные (параметры), которые требуются шаблону представления, в словарь ViewData
, Шаблон представления затем может получить доступ к динамическим данным.
В HelloWorldController.cs
измените метод Welcome
, чтобы добавить значение Message
и NumTimes
в словарь ViewData
.
Словарь ViewData
представляет собой динамический объект, а это означает, что можно использовать любой тип. Объект ViewData
не имеет определенных свойств, пока не будет добавлен какой-либо элемент.
Система привязки модели MVC автоматически сопоставляет именованные параметры name
и numTimes
из строки запроса с параметрами метода. Полный HelloWorldController
:
using Microsoft.AspNetCore.Mvc;
using System.Text.Encodings.Web;
namespace MvcMovie.Controllers;
public class HelloWorldController : Controller
{
public IActionResult Index()
{
return View();
}
public IActionResult Welcome(string name, int numTimes = 1)
{
ViewData["Message"] = "Hello " + name;
ViewData["NumTimes"] = numTimes;
return View();
}
}
Объект словаря ViewData
содержит данные, которые будут передаваться в представление.
Создайте шаблон представления приветствия с именем Views/HelloWorld/Welcome.cshtml
.
В шаблоне представления Welcome.cshtml
создайте цикл, который будет отображать строку "Hello" NumTimes
. Замените все содержимое Views/HelloWorld/Welcome.cshtml
следующим:
@{
ViewData["Title"] = "Welcome";
}
<h2>Welcome</h2>
<ul>
@for (int i = 0; i < (int)ViewData["NumTimes"]!; i++)
{
<li>@ViewData["Message"]</li>
}
</ul>
Сохраните изменения и перейдите по следующему URL-адресу:
https://localhost:{PORT}/HelloWorld/Welcome?name=Rick&numtimes=4
Данные извлекаются по URL-адресу и передаются в контроллер с помощью средства привязки модели MVC. Контроллер упаковывает данные в словарь ViewData
и передает этот объект в представление. Представление затем визуализирует данные в формате HTML для браузера.
В примере выше мы использовали словарь ViewData
для передачи данных из контроллера в представление. Далее в этом руководстве для передачи данных из контроллера в представление мы будем использовать модель представления. Подход к передаче данных на основе модели представления является предпочтительным относительно применения словаря ViewData
.
В следующем руководстве создается база данных фильмов.
В этом разделе вы внесете изменения в класс HelloWorldController
для использования файлов представления Razor. Это позволяет аккуратно инкапсулировать процесс создания HTML-ответов в клиент.
Шаблоны представлений создаются с помощью Razor. Шаблоны представлений на основе Razor:
- имеют расширение файла
.cshtml
; - Предоставить изящный способ создания HTML-выходных данных с помощью C#.
Сейчас метод Index
возвращает строку с сообщением в классе контроллера. В классе HelloWorldController
замените метод Index
следующим кодом:
public IActionResult Index()
{
return View();
}
Предыдущий код:
- вызывает метод View контроллера;
- использует шаблон представления для создания HTML-ответа.
Методы контроллера:
- называются методами действий; например, метод действия
Index
в предыдущем коде; - обычно возвращают IActionResult или класс, производный от ActionResult, а не тип, например
string
.
Добавить представление
Щелкните правой кнопкой мыши папку Views, а затем выберите Добавить > Новая папка. Назовите папку HelloWorld.
Щелкните правой кнопкой мыши папку Views/HelloWorld, а затем выберите Добавить > Новый элемент.
В диалоговом окне Добавление нового элемента MvcMovie выполните следующие действия.
- В поле поиска в правом верхнем углу введите view
- Выберите Razor Вид - Пусто
- Сохраните значение поля Имя.
Index.cshtml
- Выберите Добавить
Замените содержимое файла представления Views/HelloWorld/Index.cshtml
Razor следующим.
@{
ViewData["Title"] = "Index";
}
<h2>Index</h2>
<p>Hello from our View Template!</p>
Перейдите к https://localhost:{PORT}/HelloWorld
:
Метод
Index
вHelloWorldController
выполнил операторreturn View();
, который определяет, что метод должен использовать файл шаблона представления для отображения ответа в браузере.Имя файла шаблона представления не указано, MVC по умолчанию использует файл представления по умолчанию. Если имя файла представления не указано, возвращается представление по умолчанию. В этом примере представление по умолчанию имеет то же имя, что и метод действия
Index
. Используется шаблон/Views/HelloWorld/Index.cshtml
представления.На изображении ниже показана строка "Привет из нашего шаблона представления!", которая является жестко закодированной в представлении.
Изменение представлений и макет страниц
Выберите ссылки в меню (MvcMovie, Home и Privacy). Меню на каждой странице имеют одинаковый макет. Макет меню реализуется в Views/Shared/_Layout.cshtml
файле.
Откройте файл Views/Shared/_Layout.cshtml
.
Шаблоны макета позволяют:
- Задавать макет HTML-контейнера сайта в одном месте.
- Применение макета HTML-контейнера на нескольких страницах сайта.
Найдите строку @RenderBody()
.
RenderBody
— это заполнитель, в котором отображаются все создаваемые страницы для определенных представлений, упакованные на странице макета. Например, если щелкнуть ссылку Privacy, представление Views/Home/Privacy.cshtml
отобразится в методе RenderBody
.
Изменение заголовка, нижнего колонтитула и ссылки меню в файле макета
Замените содержимое файла Views/Shared/_Layout.cshtml
следующей разметкой: Изменения выделены:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - Movie App</title>
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
<link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
</head>
<body>
<header>
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
<div class="container-fluid">
<a class="navbar-brand" asp-area="" asp-controller="Movies" asp-action="Index">Movie App</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
<ul class="navbar-nav flex-grow-1">
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">Home</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
</li>
</ul>
</div>
</div>
</nav>
</header>
<div class="container">
<main role="main" class="pb-3">
@RenderBody()
</main>
</div>
<footer class="border-top footer text-muted">
<div class="container">
© 2022 - Movie App - <a asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
</div>
</footer>
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
@await RenderSectionAsync("Scripts", required: false)
</body>
</html>
Приведенная выше разметка вносит следующие изменения:
- Три вхождения
MvcMovie
доMovie App
. - Замена элемента привязки
<a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">MvcMovie</a>
на<a class="navbar-brand" asp-controller="Movies" asp-action="Index">Movie App</a>
.
В приведенной выше разметке asp-area=""
атрибут вспомогательной функции тега привязки и значение атрибута были опущены, так как это приложение не использует Areas.
Примечание. Контроллер Movies
не был реализован. На этом этапе ссылка Movie App
не работает.
Сохраните изменения и щелкните ссылку Privacy. Обратите внимание, что заголовок вкладки браузера отображает Privacy Политика — Приложение Movie вместо Privacy Политика — MvcMovie.
Выберите ссылку Home.
Обратите внимание, что в заголовке и тексте привязки также отображается Movie App. Внеся одно изменение в шаблон макета, мы изменили заголовок и текст ссылки на всех страницах сайта.
Просмотрите файл Views/_ViewStart.cshtml
.
@{
Layout = "_Layout";
}
Файл Views/_ViewStart.cshtml
переносит файл в каждое Views/Shared/_Layout.cshtml
представление. Свойство Layout
может задавать другое представление макета или иметь значение null
, при котором макет не используется.
Откройте файл представления Views/HelloWorld/Index.cshtml
.
Измените заголовок и элемент <h2>
, как выделено ниже:
@{
ViewData["Title"] = "Movie List";
}
<h2>My Movie List</h2>
<p>Hello from our View Template!</p>
Заголовок и элемент <h2>
немного отличаются, чтобы вы видели, какой именно фрагмент кода изменяет отображение.
ViewData["Title"] = "Movie List";
в приведенном выше коде присваивает свойству Title
словаря ViewData
значение "Movie List". Свойство Title
используется в элементе HTML <title>
на странице макета:
<title>@ViewData["Title"] - Movie App</title>
Сохраните изменения и перейдите к https://localhost:{PORT}/HelloWorld
.
Обратите внимание, что были изменены следующие элементы:
- Заголовок браузера.
- Основной заголовок.
- Дополнительные заголовки.
Если в браузере изменения не отображаются, это может означать, что содержимое кэшировано. В этом случае нажмите в браузере клавиши CTRL+F5 для принудительной загрузки ответа сервера. Заголовок браузера создается с помощью элемента ViewData["Title"]
, который задается в шаблоне представления Index.cshtml
, и дополнительного элемента "- Movie App", добавляемого в файл макета.
Содержимое Index.cshtml
шаблона представления объединяется с шаблоном Views/Shared/_Layout.cshtml
представления. В браузер отправляется один HTML-ответ. Шаблоны макетов позволяют легко вносить изменения, применяемые ко всем страницам в приложении. Дополнительные сведения см. в разделе Макет.
Небольшой фрагмент данных (сообщение "Hello from our View Template!") все равно жестко задан в коде. Приложение MVC содержит «V» (представление), «C» (контроллер), но пока не имеет «M» (модель).
Передача данных из контроллера в представление
Действия контроллера вызываются в ответ на входящий запрос URL-адреса. Код, обрабатывающий входящие запросы браузера, добавляется в класс контроллера. Контроллер извлекает данные из источника данных и определяет тип ответа, который будет отправлен в браузер. Контроллер может использовать шаблоны представлений для создания и форматирования ответа HTML, отправляемого браузеру.
Контроллер отвечает за предоставление данных, необходимых шаблону представления для отображения ответа.
Шаблоны представлений недолжны:
- выполнять бизнес-логику;
- непосредственно взаимодействовать с базой данных.
Шаблон представления должен работать только с данными, которые предоставляет ему контроллер. Поддержание этого «разделения обязанностей» помогает упростить код.
- Чистый.
- тестируемый
- поддающийся обслуживанию
Сейчас метод Welcome
в классе HelloWorldController
принимает параметры name
и ID
, после чего выводит значения напрямую в браузер.
Вместо отображения ответа в виде строки настройте контроллер для использования шаблона представления. Шаблон представления создает динамический ответ, для получения которого необходимо передать соответствующие данные из контроллера в представление. Для этого контроллер может поместить динамические данные (параметры), которые требуются шаблону представления, в словарь ViewData
, Шаблон отображения может получать доступ к динамическим данным.
В HelloWorldController.cs
измените метод Welcome
, чтобы добавить значения Message
и NumTimes
в словарь ViewData
.
Словарь ViewData
представляет собой динамический объект, а это означает, что можно использовать любой тип. Объект ViewData
не имеет определенных свойств, пока не будет добавлен какой-либо элемент.
Система привязки модели MVC автоматически сопоставляет именованные параметры name
и numTimes
из строки запроса с параметрами метода. Полный HelloWorldController
:
using Microsoft.AspNetCore.Mvc;
using System.Text.Encodings.Web;
namespace MvcMovie.Controllers;
public class HelloWorldController : Controller
{
public IActionResult Index()
{
return View();
}
public IActionResult Welcome(string name, int numTimes = 1)
{
ViewData["Message"] = "Hello " + name;
ViewData["NumTimes"] = numTimes;
return View();
}
}
Объект словаря ViewData
содержит данные, которые будут передаваться в представление.
Создайте шаблон представления приветствия с именем Views/HelloWorld/Welcome.cshtml
.
В шаблоне представления Welcome.cshtml
создайте цикл, который будет отображать строку "Hello" NumTimes
. Замените все содержимое Views/HelloWorld/Welcome.cshtml
следующим:
@{
ViewData["Title"] = "Welcome";
}
<h2>Welcome</h2>
<ul>
@for (int i = 0; i < (int)ViewData["NumTimes"]!; i++)
{
<li>@ViewData["Message"]</li>
}
</ul>
Сохраните изменения и перейдите по следующему URL-адресу:
https://localhost:{PORT}/HelloWorld/Welcome?name=Rick&numtimes=4
Данные извлекаются по URL-адресу и передаются в контроллер с помощью средства привязки модели MVC. Контроллер упаковывает данные в словарь ViewData
и передает этот объект в представление. Представление затем выводит данные в формате HTML в интернет-браузер.
В примере выше мы использовали словарь ViewData
для передачи данных из контроллера в представление. Далее в этом руководстве для передачи данных из контроллера в представление мы будем использовать модель представления. Подход к передаче данных на основе модели представления является предпочтительным относительно применения словаря ViewData
.
В следующем уроке создается база данных фильмов.
В этом разделе вы внесете изменения в класс HelloWorldController
для использования файлов представления Razor. Это аккуратно инкапсулирует процесс создания HTML-ответов для клиента.
Шаблоны представлений создаются с помощью Razor. Шаблоны представлений на основе Razor:
- имеют расширение файла
.cshtml
; - Предоставьте изящный способ создания HTML-выходных данных с помощью C#.
Сейчас метод Index
возвращает строку с сообщением в классе контроллера. В классе HelloWorldController
замените метод Index
следующим кодом:
public IActionResult Index()
{
return View();
}
Предыдущий код:
- вызывает метод View контроллера;
- использует шаблон представления для создания HTML-ответа.
Методы контроллера:
- называются методами действий; например, метод действия
Index
в предыдущем коде; - обычно возвращают IActionResult или класс, производный от ActionResult, а не тип, например
string
.
Добавить представление
Щелкните правой кнопкой мыши папку Views, а затем выберите Добавить > Новая папка. Назовите папку HelloWorld.
Щелкните правой кнопкой мыши папку Views/HelloWorld, а затем выберите Добавить > Новый элемент.
В диалоговом окне Добавление нового элемента MvcMovie выполните следующие действия.
- В поле поиска в правом верхнем углу введите view (представление).
- Выберите Вид Razor — Пусто
- Сохраните значение поля "Имя".
Index.cshtml
- Выберите Добавить
Замените содержимое файла представления Views/HelloWorld/Index.cshtml
Razor следующим.
@{
ViewData["Title"] = "Index";
}
<h2>Index</h2>
<p>Hello from our View Template!</p>
Перейдите к https://localhost:{PORT}/HelloWorld
:
Метод
Index
вHelloWorldController
выполнил операторreturn View();
, который указал, что метод должен использовать файл шаблона представления для отображения ответа в браузере.Имя файла шаблона представления не указано, MVC по умолчанию использует файл представления по умолчанию. Если имя файла представления не указано, возвращается представление по умолчанию. В этом примере представление по умолчанию имеет то же имя, что и метод действия
Index
. Используется шаблон/Views/HelloWorld/Index.cshtml
представления.На изображении ниже показана строка "Hello from our View Template!", которая жестко задана в представлении:
Измените представления и макет страниц
Выберите ссылки в меню (MvcMovie, Home и Privacy). Меню на каждой странице имеют одинаковый макет. Макет меню реализуется в Views/Shared/_Layout.cshtml
файле.
Откройте файл Views/Shared/_Layout.cshtml
.
Шаблоны макета позволяют:
- определить структуру HTML-контейнера сайта в одном месте.
- Применение макета контейнера HTML по нескольким страницам сайта.
Найдите строку @RenderBody()
.
RenderBody
— это заполнитель, в котором отображаются все создаваемые страницы для определенных представлений, упакованные на странице макета. Например, если щелкнуть ссылку Privacy, представление Views/Home/Privacy.cshtml
отобразится в методе RenderBody
.
Изменение заголовка, нижнего колонтитула и ссылки меню в файле макета
Замените содержимое файла Views/Shared/_Layout.cshtml
следующей разметкой: Изменения выделены:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - Movie App</title>
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
<link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
</head>
<body>
<header>
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
<div class="container-fluid">
<a class="navbar-brand" asp-area="" asp-controller="Movies" asp-action="Index">Movie App</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
<ul class="navbar-nav flex-grow-1">
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">Home</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
</li>
</ul>
</div>
</div>
</nav>
</header>
<div class="container">
<main role="main" class="pb-3">
@RenderBody()
</main>
</div>
<footer class="border-top footer text-muted">
<div class="container">
© 2021 - Movie App - <a asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
</div>
</footer>
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
@await RenderSectionAsync("Scripts", required: false)
</body>
</html>
Приведенная выше разметка вносит следующие изменения:
- замена трех вхождений
MvcMovie
наMovie App
; - Замена элемента привязки
<a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">MvcMovie</a>
на<a class="navbar-brand" asp-controller="Movies" asp-action="Index">Movie App</a>
.
В приведенной выше разметке asp-area=""
атрибут вспомогательной функции тега привязки и значение атрибута были опущены, так как это приложение не использует области Areas.
Примечание. Контроллер Movies
не был реализован. На этом этапе ссылка Movie App
не работает.
Сохраните изменения и щелкните ссылку Privacy. Обратите внимание, что заголовок вкладки браузера отображает Privacy Политика — Приложение Movie вместо Privacy Политика — MvcMovie.
Выберите ссылку Home.
Обратите внимание, что в заголовке и тексте привязки также отображается Movie App. Внеся одно изменение в шаблон макета, мы изменили заголовок и текст ссылки на всех страницах сайта.
Просмотрите файл Views/_ViewStart.cshtml
.
@{
Layout = "_Layout";
}
Файл Views/_ViewStart.cshtml
подключает файл Views/Shared/_Layout.cshtml
к каждому представлению. Свойство Layout
может быть использовано для установки другого макета, или его можно установить в null
, чтобы не использовать файл макета.
Откройте файл представления Views/HelloWorld/Index.cshtml
.
Измените заголовок и элемент <h2>
, как выделено ниже:
@{
ViewData["Title"] = "Movie List";
}
<h2>My Movie List</h2>
<p>Hello from our View Template!</p>
Заголовок и элемент <h2>
немного отличаются, чтобы вы видели, какой именно фрагмент кода изменяет отображение.
ViewData["Title"] = "Movie List";
в приведенном выше коде присваивает свойству Title
словаря ViewData
значение "Movie List". Свойство Title
используется в элементе HTML <title>
на странице макета:
<title>@ViewData["Title"] - Movie App</title>
Сохраните изменения и перейдите к https://localhost:{PORT}/HelloWorld
.
Обратите внимание, что были изменены следующие элементы:
- Заголовок браузера.
- Основной заголовок.
- Дополнительные заголовки.
Если в браузере изменения не отображаются, это может означать, что содержимое кэшировано. В этом случае нажмите в браузере клавиши CTRL+F5 для принудительной загрузки ответа сервера. Заголовок браузера создается с помощью атрибута ViewData["Title"]
, который задается в шаблоне представления Index.cshtml
и дополнительной строки "- Movie App", добавляемой в файл макета.
Содержимое Index.cshtml
шаблона представления объединяется с шаблоном Views/Shared/_Layout.cshtml
представления. В браузер отправляется один HTML-ответ. Шаблоны макетов позволяют легко вносить изменения, применяемые ко всем страницам в приложении. Дополнительные сведения см. в разделе Макет.
Небольшой фрагмент данных (сообщение "Hello from our View Template!") все равно жестко задан в коде. Приложение MVC имеет "V" (представление), "C" (контроллер), но пока нет "M" (модели).
Передача данных из контроллера в представление
Действия контроллера вызываются в ответ на входящий запрос URL-адреса. Код, обрабатывающий входящие запросы браузера, добавляется в класс контроллера. Контроллер извлекает данные из источника данных и определяет тип ответа, который будет отправлен в браузер. Контроллер может использовать шаблоны представлений для создания и форматирования ответа HTML, отправляемого браузеру.
Контроллер отвечает за предоставление данных, необходимых шаблону представления для отображения ответа.
Шаблоны представлений недолжны:
- выполнять бизнес-логику;
- непосредственно взаимодействовать с базой данных.
Шаблон представления должен работать только с данными, которые предоставляет ему контроллер. Поддержание такого "разделения обязанностей" помогает сохранять код:
- чисто
- тестируемый
- поддерживаемый
Сейчас метод Welcome
в классе HelloWorldController
принимает параметры name
и ID
, после чего выводит значения напрямую в браузер.
Вместо отображения ответа в виде строки настройте контроллер для использования шаблона представления. Шаблон представления создает динамический ответ, для получения которого необходимо передать соответствующие данные из контроллера в представление. Для этого контроллер может поместить динамические данные (параметры), которые требуются шаблону представления, в словарь ViewData
, Шаблон отображения может затем получить доступ к динамическим данным.
В HelloWorldController.cs
, измените метод Welcome
, чтобы добавить значения Message
и NumTimes
в словарь ViewData
.
Словарь ViewData
представляет собой динамический объект, а это означает, что можно использовать любой тип. Объект ViewData
не имеет определенных свойств, пока не будет добавлен какой-либо элемент.
Система привязки модели MVC автоматически сопоставляет именованные параметры name
и numTimes
из строки запроса с параметрами метода. Полный HelloWorldController
:
using Microsoft.AspNetCore.Mvc;
using System.Text.Encodings.Web;
namespace MvcMovie.Controllers
{
public class HelloWorldController : Controller
{
public IActionResult Index()
{
return View();
}
public IActionResult Welcome(string name, int numTimes = 1)
{
ViewData["Message"] = "Hello " + name;
ViewData["NumTimes"] = numTimes;
return View();
}
}
}
Объект словаря ViewData
содержит данные, которые будут передаваться в представление.
Создайте шаблон представления приветствия с именем Views/HelloWorld/Welcome.cshtml
.
В шаблоне представления Welcome.cshtml
создайте цикл, который будет отображать строку "Hello" NumTimes
. Замените все содержимое Views/HelloWorld/Welcome.cshtml
следующим:
@{
ViewData["Title"] = "Welcome";
}
<h2>Welcome</h2>
<ul>
@for (int i = 0; i < (int)ViewData["NumTimes"]!; i++)
{
<li>@ViewData["Message"]</li>
}
</ul>
Сохраните изменения и перейдите по следующему URL-адресу:
https://localhost:{PORT}/HelloWorld/Welcome?name=Rick&numtimes=4
Данные извлекаются по URL-адресу и передаются в контроллер с помощью средства привязки модели MVC. Контроллер упаковывает данные в словарь ViewData
и передает этот объект в представление. Представление отображает данные в формате HTML в браузере.
В примере выше мы использовали словарь ViewData
для передачи данных из контроллера в представление. Далее в этом руководстве для передачи данных из контроллера в представление мы будем использовать модель представления. Подход к передаче данных на основе модели представления является предпочтительным относительно применения словаря ViewData
.
В следующем руководстве создается база данных фильмов.
В этом разделе вы внесете изменения в класс HelloWorldController
для использования файлов представления Razor. Это четко организовывает процесс создания HTML-ответов к клиенту.
Шаблоны представлений создаются с помощью Razor. Шаблоны представлений на основе Razor:
- имеют расширение файла
.cshtml
; - обеспечьте изящный способ создания HTML-вывода с помощью C#.
Сейчас метод Index
возвращает строку с сообщением в классе контроллера. В классе HelloWorldController
замените метод Index
следующим кодом:
public IActionResult Index()
{
return View();
}
Предыдущий код:
- вызывает метод View контроллера;
- использует шаблон представления для создания HTML-ответа.
Методы контроллера:
- называются методами действий; например, метод действия
Index
в предыдущем коде; - обычно возвращают IActionResult или класс, производный от ActionResult, а не тип, например
string
.
Добавить вид
Щелкните правой кнопкой мыши папку Views, а затем выберите Добавить > Новая папка. Назовите папку HelloWorld.
Щелкните правой кнопкой мыши папку Views/HelloWorld, а затем выберите Добавить > Новый элемент.
В диалоговом окне Добавление нового элемента MvcMovie выполните следующие действия.
- В поле поиска в правом верхнем углу введите view
- Выберите Вид Razor — пустой
- Сохраните значение поля "Имя"
Index.cshtml
. - Выберите Добавить
Замените содержимое файла представления Views/HelloWorld/Index.cshtml
Razor следующим.
@{
ViewData["Title"] = "Index";
}
<h2>Index</h2>
<p>Hello from our View Template!</p>
Перейдите к https://localhost:{PORT}/HelloWorld
:
Метод
Index
вHelloWorldController
выполнил операторreturn View();
, который указал, что метод должен использовать файл шаблона представления для отображения ответа в браузере.Имя файла шаблона представления не указано, MVC по умолчанию использует файл представления по умолчанию. Если имя файла представления не указано, возвращается представление по умолчанию. В этом примере представление по умолчанию имеет то же имя, что и метод действия
Index
. Используется шаблон/Views/HelloWorld/Index.cshtml
представления.На изображении ниже показана строка "Hello from our View Template!", которая жестко задана в представлении:
Изменение видов и макета страниц
Выберите ссылки в меню (MvcMovie, Home и Privacy). Меню на каждой странице имеют одинаковый макет. Макет меню реализуется в Views/Shared/_Layout.cshtml
файле.
Откройте файл Views/Shared/_Layout.cshtml
.
Шаблоны макета позволяют:
- указать макет контейнера HTML сайта в одном месте;
- Применение макета контейнера HTML на нескольких страницах сайта.
Найдите строку @RenderBody()
.
RenderBody
— это заполнитель, в котором отображаются все страницы, которые вы создаете, обернутые в страницу макета. Например, если щелкнуть ссылку Privacy, представление Views/Home/Privacy.cshtml
отобразится в методе RenderBody
.
Изменение заголовка, нижнего колонтитула и ссылки меню в файле макета
Замените содержимое файла Views/Shared/_Layout.cshtml
следующей разметкой: Изменения выделены:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - Movie App</title>
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
<link rel="stylesheet" href="~/css/site.css" />
</head>
<body>
<header>
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
<div class="container">
<a class="navbar-brand" asp-controller="Movies" asp-action="Index">Movie App</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target=".navbar-collapse" aria-controls="navbarSupportedContent"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
<ul class="navbar-nav flex-grow-1">
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">Home</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
</li>
</ul>
</div>
</div>
</nav>
</header>
<div class="container">
<main role="main" class="pb-3">
@RenderBody()
</main>
</div>
<footer class="border-top footer text-muted">
<div class="container">
© 2020 - Movie App - <a asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
</div>
</footer>
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
@await RenderSectionAsync("Scripts", required: false)
</body>
</html>
Приведенная выше разметка вносит следующие изменения:
- Три вхождения
MvcMovie
наMovie App
. - Замена элемента привязки
<a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">MvcMovie</a>
на<a class="navbar-brand" asp-controller="Movies" asp-action="Index">Movie App</a>
.
В приведенной выше разметке атрибут asp-area=""
вспомогательной функции тега привязки и значение атрибута были опущены, так как это приложение не использует области (Areas).
Примечание. Контроллер Movies
не был реализован. На этом этапе ссылка Movie App
не работает.
Сохраните изменения и щелкните ссылку Privacy. Обратите внимание, что заголовок вкладки браузера отображает Privacy Политика — Приложение Movie вместо Privacy Политика — MvcMovie.
Выберите ссылку Home.
Обратите внимание, что в заголовке и тексте привязки также отображается Movie App. Внеся одно изменение в шаблон макета, мы изменили заголовок и текст ссылки на всех страницах сайта.
Просмотрите файл Views/_ViewStart.cshtml
.
@{
Layout = "_Layout";
}
Файл Views/_ViewStart.cshtml
добавляет файл Views/Shared/_Layout.cshtml
в каждое представление. Свойство Layout
может быть использовано для установки другого представления макета или установить его в null
, так что макетный файл использоваться не будет.
Откройте файл представления Views/HelloWorld/Index.cshtml
.
Измените заголовок и элемент <h2>
, как выделено ниже:
@{
ViewData["Title"] = "Movie List";
}
<h2>My Movie List</h2>
<p>Hello from our View Template!</p>
Заголовок и элемент <h2>
немного отличаются, чтобы вы видели, какой именно фрагмент кода изменяет отображение.
ViewData["Title"] = "Movie List";
в приведенном выше коде присваивает свойству Title
словаря ViewData
значение "Movie List". Свойство Title
используется в элементе HTML <title>
на странице макета:
<title>@ViewData["Title"] - Movie App</title>
Сохраните изменения и перейдите к https://localhost:{PORT}/HelloWorld
.
Обратите внимание, что были изменены следующие элементы:
- Заголовок браузера.
- Основной заголовок.
- Дополнительные заголовки.
Если в браузере изменения не отображаются, это может означать, что содержимое кэшировано. В этом случае нажмите в браузере клавиши CTRL+F5 для принудительной загрузки ответа сервера. Заголовок браузера создается с помощью атрибута ViewData["Title"]
, который задается в шаблоне представления Index.cshtml
и дополнительной строки "- Movie App", добавляемой в файл макета.
Содержимое Index.cshtml
шаблона представления объединяется с шаблоном Views/Shared/_Layout.cshtml
представления. В браузер отправляется один HTML-ответ. Шаблоны макетов позволяют легко вносить изменения, применяемые ко всем страницам в приложении. Дополнительные сведения см. в разделе Макет.
Небольшой фрагмент данных (сообщение "Hello from our View Template!") все равно жестко задан в коде. MVC-приложение имеет «V» (представление) и «C» (контроллер), но пока нет «M» (модели).
Передача данных из контроллера в представление
Действия контроллера вызываются в ответ на входящий запрос URL-адреса. Код, обрабатывающий входящие запросы браузера, добавляется в класс контроллера. Контроллер извлекает данные из источника данных и определяет тип ответа, который будет отправлен в браузер. Контроллер может использовать шаблоны представлений для создания и форматирования ответа HTML, отправляемого браузеру.
Контроллер отвечает за предоставление данных, необходимых шаблону представления для отображения ответа.
Шаблоны представлений недолжны:
- выполнять бизнес-логику;
- непосредственно взаимодействовать с базой данных.
Шаблон представления должен работать только с данными, которые ему предоставляет контроллер. Сохранение такого "разделения областей ответственности" помогает поддерживать код.
- чисто
- тестируемый
- поддающийся обслуживанию.
Сейчас метод Welcome
в классе HelloWorldController
принимает параметры name
и ID
, после чего выводит значения напрямую в браузер.
Вместо отображения ответа в виде строки настройте контроллер для использования шаблона представления. Шаблон представления создает динамический ответ, для получения которого необходимо передать соответствующие данные из контроллера в представление. Для этого контроллер может поместить динамические данные (параметры), которые требуются шаблону представления, в словарь ViewData
, Шаблон представления может затем получить доступ к динамическим данным.
В HelloWorldController.cs
, измените метод Welcome
, чтобы добавить значения Message
и NumTimes
в словарь ViewData
.
Словарь ViewData
представляет собой динамический объект, а это означает, что можно использовать любой тип. Объект ViewData
не имеет определенных свойств, пока не будет добавлен какой-либо элемент.
Система привязки модели MVC автоматически сопоставляет именованные параметры name
и numTimes
из строки запроса с параметрами метода. Полный HelloWorldController
:
using Microsoft.AspNetCore.Mvc;
using System.Text.Encodings.Web;
namespace MvcMovie.Controllers
{
public class HelloWorldController : Controller
{
public IActionResult Index()
{
return View();
}
public IActionResult Welcome(string name, int numTimes = 1)
{
ViewData["Message"] = "Hello " + name;
ViewData["NumTimes"] = numTimes;
return View();
}
}
}
Объект словаря ViewData
содержит данные, которые будут передаваться в представление.
Создайте шаблон представления приветствия с именем Views/HelloWorld/Welcome.cshtml
.
В шаблоне представления Welcome.cshtml
создайте цикл, который будет отображать строку "Hello" NumTimes
. Замените все содержимое Views/HelloWorld/Welcome.cshtml
следующим:
@{
ViewData["Title"] = "Welcome";
}
<h2>Welcome</h2>
<ul>
@for (int i = 0; i < (int)ViewData["NumTimes"]; i++)
{
<li>@ViewData["Message"]</li>
}
</ul>
Сохраните изменения и перейдите по следующему URL-адресу:
https://localhost:{PORT}/HelloWorld/Welcome?name=Rick&numtimes=4
Данные извлекаются по URL-адресу и передаются в контроллер с помощью средства привязки модели MVC. Контроллер упаковывает данные в словарь ViewData
и передает этот объект в представление. Затем представление отображает данные в формате HTML в браузере.
В примере выше мы использовали словарь ViewData
для передачи данных из контроллера в представление. Далее в этом руководстве для передачи данных из контроллера в представление мы будем использовать модель представления. Подход к передаче данных на основе модели представления является предпочтительным относительно применения словаря ViewData
.
В следующем руководстве создается база данных фильмов.
В этом разделе вы внесете изменения в класс HelloWorldController
для использования файлов представления Razor. Это аккуратно инкапсулирует процесс создания HTML-ответов для клиента.
Шаблоны представлений создаются с помощью Razor. Шаблоны представлений на основе Razor:
- имеют расширение файла
.cshtml
; - предоставить элегантный способ создания HTML-кода с помощью C#.
Сейчас метод Index
возвращает строку с сообщением в классе контроллера. В классе HelloWorldController
замените метод Index
следующим кодом:
public IActionResult Index()
{
return View();
}
Предыдущий код:
- вызывает метод View контроллера;
- использует шаблон представления для создания HTML-ответа.
Методы контроллера:
- называются методами действий; например, метод действия
Index
в предыдущем коде; - обычно возвращают IActionResult или класс, производный от ActionResult, а не тип, например
string
.
Добавить представление
Щелкните правой кнопкой мыши папку Views, а затем выберите Добавить > Новая папка. Назовите папку HelloWorld.
Щелкните правой кнопкой мыши папку Views/HelloWorld, а затем выберите Добавить > Новый элемент.
В диалоговом окне Добавление нового элемента MvcMovie выполните следующие действия.
- В поле поиска в правом верхнем углу введите view (представление).
- Выберите Razor Вид - пустой
- Сохраните значение поля «Имя»,
Index.cshtml
. - Выберите Добавить
Замените содержимое файла представления Views/HelloWorld/Index.cshtml
Razor следующим.
@{
ViewData["Title"] = "Index";
}
<h2>Index</h2>
<p>Hello from our View Template!</p>
Перейдите к https://localhost:{PORT}/HelloWorld
:
Метод
Index
вHelloWorldController
выполнил операторreturn View();
, который указал, что метод должен использовать файл шаблона представления для отображения ответа в браузере.Имя файла шаблона представления не указано, MVC по умолчанию использует файл представления по умолчанию. Если имя файла представления не указано, возвращается представление по умолчанию. В этом примере представление по умолчанию имеет то же имя, что и метод действия
Index
. Используется шаблон/Views/HelloWorld/Index.cshtml
представления.На изображении ниже показана строка "Привет из нашего шаблона представления!", которая задана в представлении:
Измените представления и макет страниц
Выберите ссылки в меню (MvcMovie, Home и Privacy). Меню на каждой странице имеют одинаковый макет. Макет меню реализуется в Views/Shared/_Layout.cshtml
файле.
Откройте файл Views/Shared/_Layout.cshtml
.
Шаблоны макета позволяют:
- Указать оформление HTML-контейнера сайта в одном месте.
- Применение макета контейнера HTML на нескольких страницах сайта.
Найдите строку @RenderBody()
.
RenderBody
является заполнителем, в котором отображаются все созданные вами страницы представлений, встроенные в страницу макета. Например, если щелкнуть ссылку Privacy, представление Views/Home/Privacy.cshtml
отобразится в методе RenderBody
.
Изменение заголовка, нижнего колонтитула и ссылки меню в файле макета
Замените содержимое файла Views/Shared/_Layout.cshtml
следующей разметкой: Изменения выделены:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - Movie App</title>
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
<link rel="stylesheet" href="~/css/site.css" />
</head>
<body>
<header>
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
<div class="container">
<a class="navbar-brand" asp-controller="Movies" asp-action="Index">Movie App</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target=".navbar-collapse" aria-controls="navbarSupportedContent"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse">
<ul class="navbar-nav flex-grow-1">
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">Home</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
</li>
</ul>
</div>
</div>
</nav>
</header>
<div class="container">
<main role="main" class="pb-3">
@RenderBody()
</main>
</div>
<footer class="border-top footer text-muted">
<div class="container">
© 2020 - Movie App - <a asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
</div>
</footer>
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
@RenderSection("Scripts", required: false)
</body>
</html>
Приведенная выше разметка вносит следующие изменения:
- Замена трёх вхождений
MvcMovie
наMovie App
. - Замена элемента привязки
<a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">MvcMovie</a>
на<a class="navbar-brand" asp-controller="Movies" asp-action="Index">Movie App</a>
.
В приведенной выше разметке asp-area=""
и атрибут вспомогательной функции тега anchor, а также значение атрибута были опущены, так как это приложение не использует Areas.
Примечание. Контроллер Movies
не был реализован. На этом этапе ссылка Movie App
не работает.
Сохраните изменения и щелкните ссылку Privacy. Обратите внимание, что заголовок вкладки браузера отображает Privacy Политика — Приложение Movie вместо Privacy Политика — MvcMovie.
Выберите ссылку Home.
Обратите внимание, что в заголовке и тексте привязки также отображается Movie App. Внеся одно изменение в шаблон макета, мы изменили заголовок и текст ссылки на всех страницах сайта.
Просмотрите файл Views/_ViewStart.cshtml
.
@{
Layout = "_Layout";
}
Файл Views/_ViewStart.cshtml
подключает файл Views/Shared/_Layout.cshtml
к каждому представлению. Свойство Layout
может использоваться для установки другого представления макета или для установки на null
, чтобы макетный файл не использовался.
Откройте файл представления Views/HelloWorld/Index.cshtml
.
Измените заголовок и элемент <h2>
, как выделено ниже:
@{
ViewData["Title"] = "Movie List";
}
<h2>My Movie List</h2>
<p>Hello from our View Template!</p>
Заголовок и элемент <h2>
немного отличаются, чтобы вы видели, какой именно фрагмент кода изменяет отображение.
ViewData["Title"] = "Movie List";
в приведенном выше коде присваивает свойству Title
словаря ViewData
значение "Movie List". Свойство Title
используется в элементе HTML <title>
на странице макета:
<title>@ViewData["Title"] - Movie App</title>
Сохраните изменения и перейдите к https://localhost:{PORT}/HelloWorld
.
Обратите внимание, что были изменены следующие элементы:
- Заголовок браузера.
- Основной заголовок.
- Дополнительные заголовки.
Если в браузере изменения не отображаются, это может означать, что содержимое кэшировано. В этом случае нажмите в браузере клавиши CTRL+F5 для принудительной загрузки ответа сервера. Заголовок браузера создается с помощью атрибута ViewData["Title"]
, который задается в шаблоне представления Index.cshtml
и дополнительной строки "- Movie App", добавляемой в файл макета.
Содержимое Index.cshtml
шаблона представления объединяется с шаблоном Views/Shared/_Layout.cshtml
представления. В браузер отправляется один HTML-ответ. Шаблоны макетов позволяют легко вносить изменения, применяемые ко всем страницам в приложении. Дополнительные сведения см. в разделе Макет.
Небольшой фрагмент данных (сообщение "Hello from our View Template!") все равно жестко задан в коде. Приложение MVC имеет V (представление) и C (контроллер), но пока нет M (модели).
Передача данных из контроллера в представление
Действия контроллера вызываются в ответ на входящий запрос URL-адреса. Код, обрабатывающий входящие запросы браузера, добавляется в класс контроллера. Контроллер извлекает данные из источника данных и определяет тип ответа, который будет отправлен в браузер. Контроллер может использовать шаблоны представлений для создания и форматирования ответа HTML, отправляемого браузеру.
Контроллер отвечает за предоставление данных, необходимых шаблону представления для отображения ответа.
Шаблоны представлений недолжны:
- выполнять бизнес-логику;
- непосредственно взаимодействовать с базой данных.
Шаблон представления должен работать только с данными, которые ему предоставляет контроллер. Подобное разделение сфер ответственности позволяет обеспечить максимальную оптимизацию кода, а также удобство его
- чистый
- тестируемый
- поддерживаемый.
Сейчас метод Welcome
в классе HelloWorldController
принимает параметры name
и ID
, после чего выводит значения напрямую в браузер.
Вместо отображения ответа в виде строки настройте контроллер для использования шаблона представления. Шаблон представления создает динамический ответ, для получения которого необходимо передать соответствующие данные из контроллера в представление. Для этого контроллер может поместить динамические данные (параметры), которые требуются шаблону представления, в словарь ViewData
, Затем шаблон представления сможет получить доступ к динамическим данным.
В HelloWorldController.cs
измените метод Welcome
для добавления значений Message
и NumTimes
в словарь ViewData
.
Словарь ViewData
представляет собой динамический объект, а это означает, что можно использовать любой тип. Объект ViewData
не имеет определенных свойств, пока не будет добавлен какой-либо элемент.
Система привязки модели MVC автоматически сопоставляет именованные параметры name
и numTimes
из строки запроса с параметрами метода. Полный HelloWorldController
:
using Microsoft.AspNetCore.Mvc;
using System.Text.Encodings.Web;
namespace MvcMovie.Controllers
{
public class HelloWorldController : Controller
{
public IActionResult Index()
{
return View();
}
public IActionResult Welcome(string name, int numTimes = 1)
{
ViewData["Message"] = "Hello " + name;
ViewData["NumTimes"] = numTimes;
return View();
}
}
}
Объект словаря ViewData
содержит данные, которые будут передаваться в представление.
Создайте шаблон представления приветствия с именем Views/HelloWorld/Welcome.cshtml
.
В шаблоне представления Welcome.cshtml
создайте цикл, который будет отображать строку "Hello" NumTimes
. Замените все содержимое Views/HelloWorld/Welcome.cshtml
следующим:
@{
ViewData["Title"] = "Welcome";
}
<h2>Welcome</h2>
<ul>
@for (int i = 0; i < (int)ViewData["NumTimes"]; i++)
{
<li>@ViewData["Message"]</li>
}
</ul>
Сохраните изменения и перейдите по следующему URL-адресу:
https://localhost:{PORT}/HelloWorld/Welcome?name=Rick&numtimes=4
Данные извлекаются по URL-адресу и передаются в контроллер с помощью средства привязки модели MVC. Контроллер упаковывает данные в словарь ViewData
и передает этот объект в представление. Представление отображает данные в формате HTML в браузере.
В примере выше мы использовали словарь ViewData
для передачи данных из контроллера в представление. Далее в этом руководстве для передачи данных из контроллера в представление мы будем использовать модель представления. Подход к передаче данных на основе модели представления является предпочтительным относительно применения словаря ViewData
.
В следующем руководстве создается база данных фильмов.
ASP.NET Core