Макет в ASP.NET Core
Авторы: Стив Смит (Steve Smith) и Дейв Брок (Dave Brock)
На страницах и в представлениях часто есть общие визуальные и программные элементы. В этой статье демонстрируются следующие возможности.
- Использование общих макетов.
- Совместное использование директив.
- Запуск общего кода до отрисовки страниц или представлений.
В этом документе рассматриваются макеты двух различных подходов к ASP.NET Core MVC: Razor Pages и контроллеров с представлениями. С этой точки зрения различия минимальны:
- Razor Страницы находятся в папке Pages .
- Контроллеры с представлениями используют папку Views для представлений.
Что такое макет
Большинство веб-приложений имеют общий макет, который обеспечивает согласованный пользовательский интерфейс при переходе между страницами. Макет, как правило, включает в себя общие элементы пользовательского интерфейса, такие как верхний и нижний колонтитулы, а также элементы навигации или меню.
Структуры HTML, такие как скрипты и таблицы стилей, также часто используются совместно несколькими страницами в приложении. Все эти общие элементы могут определяться в файле макета, на который затем может ссылаться на любое представление в приложении. Макеты позволяют сократить дублирование кода в представлениях.
В соответствии с соглашением макет по умолчанию для приложения ASP.NET Core имеет имя _Layout.cshtml
. В новых проектах ASP.NET Core, созданных с применением шаблонов, используются следующие файлы макета.
Razor Страниц:
Pages/Shared/_Layout.cshtml
Контроллер с представлениями:
Views/Shared/_Layout.cshtml
Макет определяет шаблон верхнего уровня для представлений в приложении. Для приложений макет не требуется. В приложении может быть определено несколько макетов для разных представлений.
В следующем коде показан файл макета для проекта, созданного по шаблону, с контроллером и представлениями:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - WebApplication1</title>
<environment include="Development">
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
<link rel="stylesheet" href="~/css/site.css" />
</environment>
<environment exclude="Development">
<link rel="stylesheet" href="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.7/css/bootstrap.min.css"
asp-fallback-href="~/lib/bootstrap/dist/css/bootstrap.min.css"
asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute" />
<link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true" />
</environment>
</head>
<body>
<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a asp-page="/Index" class="navbar-brand">WebApplication1</a>
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li><a asp-page="/Index">Home</a></li>
<li><a asp-page="/About">About</a></li>
<li><a asp-page="/Contact">Contact</a></li>
</ul>
</div>
</div>
</nav>
<partial name="_CookieConsentPartial" />
<div class="container body-content">
@RenderBody()
<hr />
<footer>
<p>© 2018 - WebApplication1</p>
</footer>
</div>
<environment include="Development">
<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>
</environment>
<environment exclude="Development">
<script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-3.3.1.min.js"
asp-fallback-src="~/lib/jquery/dist/jquery.min.js"
asp-fallback-test="window.jQuery"
crossorigin="anonymous"
integrity="sha384-tsQFqpEReu7ZLhBV2VZlAu7zcOV+rXbYlF2cqB8txI/8aZajjp4Bqd+V6D5IgvKT">
</script>
<script src="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.7/bootstrap.min.js"
asp-fallback-src="~/lib/bootstrap/dist/js/bootstrap.min.js"
asp-fallback-test="window.jQuery && window.jQuery.fn && window.jQuery.fn.modal"
crossorigin="anonymous"
integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa">
</script>
<script src="~/js/site.min.js" asp-append-version="true"></script>
</environment>
@RenderSection("Scripts", required: false)
</body>
</html>
Указание макета
Razor представления имеют Layout
свойство. С его помощью указывается макет в отдельных представлениях:
@{
Layout = "_Layout";
}
Указанный макет может использовать полный путь (например, /Pages/Shared/_Layout.cshtml
или) или /Views/Shared/_Layout.cshtml
частичное имя (например: _Layout
). При указании Razor частичного имени подсистема просмотра ищет файл макета с помощью стандартного процесса обнаружения. Сначала поиск выполняется в папке, где существует метод обработчика (или контроллер), а затем в папке Shared. Процесс обнаружения аналогичен тому, который применяется для поиска частичных представлений.
По умолчанию каждый макет должен вызывать метод RenderBody
. При каждом вызове RenderBody
содержимое представления будет преобразовываться для просмотра.
Разделы
Макет может при необходимости ссылаться на один или несколько разделов, вызывая метод RenderSection
. Разделы — это средство для упорядочения размещения определенных элементов на странице. В каждом вызове RenderSection
можно указывать, является ли раздел обязательным или необязательным:
<script type="text/javascript" src="~/scripts/global.js"></script>
@RenderSection("Scripts", required: false)
Если обязательный раздел не найден, создается исключение. Отдельные представления указывают содержимое, отображаемое в разделе с помощью синтаксиса @section
Razor . Если на странице или в представлении определяется раздел, он должен быть преобразован для просмотра (в противном случае произойдет ошибка).
Пример @section
определения в Razor представлении Pages:
@section Scripts {
<script type="text/javascript" src="~/scripts/main.js"></script>
}
В приведенном выше коде scripts/main.js
добавляется в scripts
раздел на странице или представлении. Другие страницы или представления в одном приложении могут не требовать этот скрипт и не определять раздел скриптов.
Следующая разметка использует вспомогательный элемент частичного тега для отрисовки_ValidationScriptsPartial.cshtml
:
@section Scripts {
<partial name="_ValidationScriptsPartial" />
}
Предыдущая разметка была создана с помощью шаблонов Identity.
Разделы, определенные на странице или в представлении, доступны только непосредственно на странице макета. На них нельзя ссылаться из частичных представлений, компонентов представлений или других частей системы представлений.
Пропуск разделов
По умолчанию тело и все разделы страницы содержимого должны преобразовываться для просмотра страницей макета. Обработчик Razor представлений применяет это путем отслеживания того, был ли отрисован текст и каждый раздел.
Чтобы подсистема представлений пропустила тело или разделы, вызовите методы IgnoreBody
и IgnoreSection
.
Текст и каждый раздел страницы Razor должны отображаться или игнорироваться.
Импорт общих директив
Представления и страницы могут использовать Razor директивы для импорта пространств имен и внедрения зависимостей. Директивы, используемые несколькими представлениями, можно указать в общем файле _ViewImports.cshtml
. Файл _ViewImports
поддерживает следующие директивы:
@addTagHelper
@removeTagHelper
@tagHelperPrefix
@using
@model
@inherits
@inject
@namespace
Файл не поддерживает другие Razor функции, такие как функции и определения разделов.
Пример файла _ViewImports.cshtml
:
@using WebApplication1
@using WebApplication1.Models
@using WebApplication1.Models.AccountViewModels
@using WebApplication1.Models.ManageViewModels
@using Microsoft.AspNetCore.Identity
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
_ViewImports.cshtml
Файл для приложения MVC ASP.NET Core обычно помещается в папку Pages (или Views). _ViewImports.cshtml
Файл можно поместить в любую папку, в этом случае она будет применена только к страницам или представлениям в этой папке и ее вложенным папкам. Файлы _ViewImports
обрабатываются начиная с корневого уровня, а затем для каждой папки вплоть до расположения самой страницы или представления. Параметры _ViewImports
, заданные на корневом уровне, можно переопределить на уровне папки.
Например, предположим, что:
- Файл корневого уровня
_ViewImports.cshtml
включает@model MyModel1
и@addTagHelper *, MyTagHelper1
. - Вложенная папка
_ViewImports.cshtml
содержит@model MyModel2
и@addTagHelper *, MyTagHelper2
.
Страницы и представления во вложенной папке будут иметь доступ к вспомогательным функциям тегов и модели MyModel2
.
Если несколько _ViewImports.cshtml
файлов находятся в иерархии файлов, объединенное поведение директив:
@addTagHelper
,@removeTagHelper
: выполняются все директивы по порядку;@tagHelperPrefix
: ближайшая к представлению директива переопределяет все остальные;@model
: ближайшая к представлению директива переопределяет все остальные;@inherits
: ближайшая к представлению директива переопределяет все остальные;@using
: включаются все директивы, повторяющиеся пропускаются;@inject
: для каждого свойства ближайшая к представлению директива переопределяет все остальные директивы с тем же именем свойства.
Выполнение кода перед каждым представлением
Код, который должен выполняться перед каждым представлением или страницей _ViewStart.cshtml
, должен быть помещен в файл. По соглашению _ViewStart.cshtml
файл находится в папке Pages (или Views). Операторы, перечисленные в файле _ViewStart.cshtml
, выполняются перед каждым полным представлением (но не перед макетами и не перед частичными представлениями). Так же как файлы ViewImports.cshtml, файлы _ViewStart.cshtml
являются иерархическими. _ViewStart.cshtml
Если файл определен в папке представления или страниц, он будет выполняться после того, как он определен в корневой папке Pages (или Views) (если таковые есть).
Пример файла _ViewStart.cshtml
:
@{
Layout = "_Layout";
}
Приведенный файл предписывает всем представлениям использовать макет _Layout.cshtml
.
_ViewStart.cshtml
и _ViewImports.cshtml
обычно не помещаются в папку /Pages/Shared (или /Views/Shared). Версии этих файлов, которые должны действовать на уровне приложения, следует помещать непосредственно в папку /Pages (или /Views).
ASP.NET Core