Часть 3. Добавление представления в приложение MVC ASP.NET Core
Примечание.
Это не последняя версия этой статьи. В текущем выпуске см . версию .NET 9 этой статьи.
Предупреждение
Эта версия ASP.NET Core больше не поддерживается. Дополнительные сведения см. в статье о политике поддержки .NET и .NET Core. В текущем выпуске см . версию .NET 8 этой статьи.
Внимание
Эта информация относится к предварительному выпуску продукта, который может быть существенно изменен до его коммерческого выпуска. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.
В текущем выпуске см . версию .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">
© 2024 - 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 предоставляет представление, вы реализуете контроллер, однако модели на данный момент еще нет.
Передача данных из контроллера в представление
Действия контроллера вызываются в ответ на входящий запрос 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 предоставляет представление, вы реализуете контроллер, однако модели на данный момент еще нет.
Передача данных из контроллера в представление
Действия контроллера вызываются в ответ на входящий запрос 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">
© 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 предоставляет представление, вы реализуете контроллер, однако модели на данный момент еще нет.
Передача данных из контроллера в представление
Действия контроллера вызываются в ответ на входящий запрос 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 предоставляет представление, вы реализуете контроллер, однако модели на данный момент еще нет.
Передача данных из контроллера в представление
Действия контроллера вызываются в ответ на входящий запрос 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 предоставляет представление, вы реализуете контроллер, однако модели на данный момент еще нет.
Передача данных из контроллера в представление
Действия контроллера вызываются в ответ на входящий запрос 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 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=""
и значение атрибута были опущены, так как это приложение не использует области (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 предоставляет представление, вы реализуете контроллер, однако модели на данный момент еще нет.
Передача данных из контроллера в представление
Действия контроллера вызываются в ответ на входящий запрос 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