Данное руководство устарело. Актуальное руководство: Руководство по ASP.NET Core 7
Когда у нас в проекте много представлений, и все они содержат какие-то общие элементы, то вместо того, чтобы пописывать все эти элементы в каждом представлении, гораздо удобнее задать один общий шаблон. В этом случае при изменении каких-то общих элементов будет достаточно изменить один раз в общем шаблоне, не изменяя всех остальных представлений. В ASP.NET MVC таким шаблоном являются мастер-страницы.
Мастер-страницы применяются для создания единообразного, унифицированного вида сайта. По сути мастер-страницы - это те же самые представления, которе могут включать в себя другие представления. Например, можно определить на мастер-странице общие для всех остальных представлений меню, а также подключить общие стили и скрипты. В итоге нам не придется на каждом отдельном представлении прописывать путь к файлам стилей, а потом при необходимости его изменять. А специальные теги позволяют вставлять в определенное место на мастер-страницах другие представления.
По умолчанию при создании нового проекта ASP.NET MVC Core в проект уже добавляется мастер-страница под названием _Layout.chtml, которую можно найти в каталоге Views/Shared. В приложении из шестой главы мы ее изменили следующим образом:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>@ViewData["Title"]</title> <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" /> </head> <body> <!--меню--> <nav class="navbar navbar-inverse"> <div class="container"> <div> <ul class="nav navbar-nav"> <li><a href="~/Home/Index" class="navbar-brand">Главная</a></li> </ul> </div> </div> </nav> <!--основной контент--> <div class="container body-content"> @RenderBody() <hr /> <footer> <p>© 2015 - MobileStore</p> </footer> </div> </body> </html>
Код мастер-страницы напоминает полноценную веб-страницу: здесь присутсвуют основные теги <html>
, <head>
,
<body>
и так далее. И также здесь могут использоваться конструкции Razor. Фактически это то же самое представление.
Главное же отличие от обычных представлений состоит в использовании метода @RenderBody(), который является плейсхолдером
и на место которого потом будут подставляться другие представления, использующие данную мастер-страницу. В итоге мы сможем легко установить для
всех представлений веб-приложения единообразный стиль оформления.
По умолчанию представления уже подключают мастер-страницу за счет файла _ViewStart.cshtml. Этот файл можно найти в проекте в папке Views. Код этого файла добавляется в самое начало кода преставлений при их запуске. При этом файлы представлений, к которым применяется _ViewStart.cshtml, должны находиться с этим файлов в одном каталоге.
По умолчанию файл _ViewStart.cshtml
содержит следующий код:
@{ Layout = "_Layout"; }
В каждом представлении через синтаксис Razor доступно свойство Layout, которое хранит ссылку на мастер-страницу. Здесь в качестве мастер страницы устанавливается файл _Layout.cshtml. При этом расширение можно не использовать.
Когда будет происходить рендеринг представления, то система будет искать мастер страницу _Layout по следующим путям:
/Views/[Название_контроллера]/_Layout.cshtml /Views/Shared/_Layout.cshtml
Если в обеих папках: и в /Views/[Название_контроллера], и в /Views/Shared/ имеется файл с одинаковым
именем, например, _Layout.cshtml
, то к представлению применяется файл, который находится с ним в одной папке как более приоритетный.
То есть таким образом мы можем определить для представлений каждого отдельного контроллера или представлений, которые находятся в одной папке, свою отдельную мастер-страницу.
Если вдруг мы хотим глобально по всему проекту поменять мастер-страницу на другой файл, который расположен в какой-то другой папке, например, в корне каталога Views, то нам надо использовать полный путь к файлу:
@{ Layout = "~/Views/_Layout.cshtml"; }
При необходимости мы можем использовать несколько мастер-страниц. Добавим в папку Views новую мастер-страницу. Для этого нажмем правой кнопкой мыши на папку Views и в выпадающем меню выберем Add -> New Item. Для более быстрого создания мастер-страницы Visual Studio предлагает специальный шаблон Razor Layout:
Назовем файл _Master.cshtml.
Код из _ViewStart.cshtml выполняется до любого кода в представлении. И чтобы переопределить мастер-страницу, в представлении доcтаточно установить
свойство Layout. Мы можем вообще не использовать мастер-страницу, тогда нам надо присвоить значение null
:
@{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>Home Page</title> </head> <body> <h2>Представление Index.cshtml</h2> </body> </html>
Либо можно использовать какую-нибудь уже имеющуюся мастер-страницу, указав к ней полный путь:
@{ ViewData["Title"] = "Home Page"; Layout = "~/Views/_Master.cshtml"; } <h2>Представление Index.cshtml</h2>
Кроме метода RenderBody()
, который вставляет освновное содержимое представлений, мастер-страниц может также использовать специальный
метод RenderSection()
для вставки секций. Мастер-страница может иметь несколько секций, куда представления могут поместить свое содержимое.
Например, добавим к мастер-странице _Master.cshtml
секцию footer:
<!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>@ViewBag.Title</title> </head> <body> <div> @RenderBody() </div> <footer>@RenderSection("Footer")</footer> </body> </html>
Теперь при запуске предыдущего представления Index мы получим ошибку, так как секция Footer не определена. По умолчанию представление должно
передавать содержание для каждой секции мастер-страницы. Поэтому добавим вниз представления Index секцию footer. Это мы можем сделать с помощью
выражения @section
:
@{ ViewData["Title"] = "Home Page"; Layout = "~/Views/_Master.cshtml"; } <h2>Представление Index.cshtml</h2> @section Footer { Все права защищены. Site Corp. 2016. }
Но при таком подходе, если у нас есть куча представлений, и мы вдруг захотели определить новую секцию на мастер-странице, нам придется изменить все имеющиеся представления, что не очень удобно. В этом случае мы можем воспользоваться одним из вариантов гибкой настройки секций.
Первый вариант заключается в использовании перегруженной версии метода RenderSection, которая позволяет указать, что
данную секцию не обязательно определять в представлении. Чтобы отметить секцию Footer
в качестве необязательной, надо передать в метод
в качестве второго параметра значение false
:
<footer>@RenderSection("Footer", false)</footer>
Второй вариант позволяет задать содержание секции по умолчанию, если данная секция не определена в представлении:
<footer> @if (IsSectionDefined("Footer")) { @RenderSection("Footer") } else { <span>Содержание элемента footer по умолчанию.</span> } </footer>