Layout in ASP.NET Core
Von Steve Smith und Dave Brock
Seiten und Ansichten beinhalten häufig sowohl visuelle als auch programmgesteuerte Elemente. Dieser Artikel demonstriert Folgendes:
- Verwendung von allgemeinen Layouts
- Freigeben von Anweisungen
- Führen Sie den allgemeinen Code aus, bevor Sie Seiten oder Ansichten rendern.
In diesem Dokument werden Layouts für zwei verschiedene Ansätze zu ASP.NET Core MVC erläutert: Razor Pages und Controller mit Ansichten. In diesem Thema sind die Unterschiede minimal:
- Razor Pages befindet sich im Ordner Pages.
- Controller mit Ansichten verwenden einen Ordner namens Views für Ansichten.
Was ist ein Layout?
Die meisten Web-Apps haben ein gebräuchliches Layout, das dem Benutzer beim Navigieren auf den Seiten ein konsistentes Verhalten bietet. Das Layout enthält normalerweise allgemeine Benutzeroberflächenelemente wie App-Header, Navigations- oder Menüelemente sowie eine Fußzeile.
Oft verwendete HTML-Strukturen wie Skripts und Stylesheets werden auch häufig von vielen Seiten in einer App genutzt. Alle diese gemeinsamen Elemente werden in einer Layoutdatei definiert, auf die dann von jeder Ansicht einer App verwiesen werden kann. Layouts verringern Codeduplikate in Ansichten.
Gemäß Konvention ist _Layout.cshtml
das Standardlayout für eine ASP.NET Core-App. Für neue ASP.NET Core-Projekte, die mit den Vorlagen erstellt wurden, sind folgende Layoutdateien vorhanden:
Razor Pages:
Pages/Shared/_Layout.cshtml
Controller mit Ansichten:
Views/Shared/_Layout.cshtml
Das Layout definiert eine übergeordnete Vorlage für die Ansichten einer App. Für Apps ist kein Layout erforderlich. Sie können allerdings mehrere Layouts mit unterschiedlichen Ansichten aufweisen.
Der folgende Code zeigt die Layoutdatei für eine Vorlage, die mit dem Projekt mit einem Controller und Ansichten erstellt wurde:
<!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>
Festlegen eines Layouts
Razor-Ansichten verfügen über eine Layout
-Eigenschaft. Durch Festlegen dieser Eigenschaft wird das Layout der jeweiligen Ansicht bestimmt:
@{
Layout = "_Layout";
}
Das Layout kann mit seinem vollständigen Pfad (Beispiel: /Pages/Shared/_Layout.cshtml
oder /Views/Shared/_Layout.cshtml
) oder über einen Teil seines Namens angegeben werden (Beispiel: _Layout
). Wird ein Teil des Namens angegeben, dann sucht die Razor-Ansichts-Engine die Layoutdatei unter Verwendung des standardmäßigen Ermittlungsprozesses. Der Ordner, in dem sich die die Handlermethode (oder der Controller) befindet, wird zuerst durchsucht und danach der Ordner Shared. Dieser Ermittlungsprozess ist identisch mit dem Prozess zum Auffinden von Teilansichten.
Standardmäßig muss jedes Layout RenderBody
aufrufen. Wo immer der Aufruf von RenderBody
platziert ist, wird der Inhalt der Ansicht gerendert.
Abschnitte
Optional kann ein Layout auf mindestens einen Abschnitt verweisen, indem es RenderSection
aufruft. Abschnitte geben an, wo bestimmte Seitenelemente platziert werden sollen. Jeder Aufruf von RenderSection
kann angeben, ob dieser Abschnitt erforderlich ist:
<script type="text/javascript" src="~/scripts/global.js"></script>
@RenderSection("Scripts", required: false)
Wenn ein erforderlicher Bereich nicht gefunden werden kann, wird eine Ausnahme ausgelöst. Einzelne Ansichten verwenden die @section
-Razor-Syntax , um den in einem Abschnitt zu rendernden Inhalt anzugeben. Wenn eine Seite oder eine Ansicht einen Abschnitt definiert, muss dieser auch gerendert werden. Andernfalls tritt ein Fehler auf.
Eine Beispieldefinition von @section
in einer Razor Pages-Ansicht:
@section Scripts {
<script type="text/javascript" src="~/scripts/main.js"></script>
}
Im vorangehenden Code wird scripts/main.js
dem Abschnitt scripts
auf einer Seite oder in einer Ansicht hinzugefügt. Andere Seiten oder Ansichten in der gleichen App benötigen dieses Skript möglicherweise nicht und definieren einen Abschnitt zu Skripts.
In der folgenden Markupdatei wird die Datei _ValidationScriptsPartial.cshtml
mit dem Partial-Taghilfsprogramm gerendert:
@section Scripts {
<partial name="_ValidationScriptsPartial" />
}
Die vorhergehende Markupdatei wurde durch Gerüst-Identity generiert.
Die Abschnitte, die auf einer Seite oder in einer Ansicht definiert wurden, stehen nur auf deren Layoutseite zur Verfügung. Teilansichten, Ansichtskomponenten und andere Teile eines Ansichtssystems können nicht auf sie verweisen.
Ignorieren von Abschnitten
Standardmäßig müssen der Text und die Abschnitte einer Inhaltsseite alle von der Layoutseite gerendert werden. Die Razor-Ansichts-Engine erzwingt dies, indem sie erfasst, ob der Text und jeder Abschnitt gerendert wurde.
Rufen Sie die Methoden IgnoreBody
und IgnoreSection
auf, um die Ansichtsengine anzuweisen, den Text oder die Abschnitte zu ignorieren.
Der Text und jeder Abschnitt einer Razor Page müssen entweder gerendert oder ignoriert werden.
Importieren gemeinsam verwendeter Anweisungen
Seiten und Ansichten können Razor-Anweisungen zum Importieren von Namespaces und Abhängigkeitsinjektion verwenden. Anweisungen, die von mehreren Ansichten gemeinsam verwendet werden, können in einer gemeinsam verwendeten _ViewImports.cshtml
-Datei angegeben werden. Die _ViewImports
-Datei unterstützt die folgenden Anweisungen:
@addTagHelper
@removeTagHelper
@tagHelperPrefix
@using
@model
@inherits
@inject
@namespace
Die Datei unterstützt keine anderen Razor-Features wie Funktionen und Abschnittsdefinitionen.
Eine _ViewImports.cshtml
-Beispieldatei:
@using WebApplication1
@using WebApplication1.Models
@using WebApplication1.Models.AccountViewModels
@using WebApplication1.Models.ManageViewModels
@using Microsoft.AspNetCore.Identity
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
Die Datei _ViewImports.cshtml
für eine ASP.NET Core MVC-App befindet sich normalerweise im Ordner Pages (oder Views). Eine Datei _ViewImports.cshtml
kann auch in einen anderen Ordner verschoben werden. In diesem Fall wird sie nur auf Seiten oder Ansichten in diesem Ordner und in dessen Unterordnern angewendet. _ViewImports
-Dateien werden beginnend ab der Stammebene verarbeitet und dann einzeln für jeden Ordner bis zum Speicherort der Seite oder der Ansicht selbst. Die _ViewImports
-Einstellungen auf der Stammebene werden möglicherweise auf Ordnerebene außer Kraft gesetzt.
Nehmen Sie beispielsweise Folgendes an:
- Die Datei
_ViewImports.cshtml
auf Stammebene umfasst@model MyModel1
and@addTagHelper *, MyTagHelper1
. - Eine Unterordnerdatei
_ViewImports.cshtml
enthält@model MyModel2
und@addTagHelper *, MyTagHelper2
.
Seiten und Ansichten im Unterordner haben Zugriff auf beide Taghilfsprogramme und das Modell MyModel2
.
Wenn sich mehrere Dateien _ViewImports.cshtml
in der Hierarchie befinden, umfasst das kombinierte Verhalten der Anweisungen Folgendes:
@addTagHelper
,@removeTagHelper
: werden nach der Reihe ausgeführt@tagHelperPrefix
: dasjenige, das der Ansicht am Nächsten ist, setzt die anderen außer Kraft@model
: dasjenige, das der Ansicht am Nächsten ist, setzt die anderen außer Kraft@inherits
: dasjenige, das der Ansicht am Nächsten ist, setzt die anderen außer Kraft@using
: alle einbezogen; Duplikate werden ignoriert@inject
: dasjenige, das der Ansicht am Nächsten ist, setzt für jede Eigenschaft alle anderen mit dem gleichen Namen außer Kraft
Ausführen von Code vor jeder Ansicht
Code, der ausgeführt werden muss, bevor die einzelnen Ansichten oder Seiten in die Datei _ViewStart.cshtml
platziert werden. Gemäß der Konvention befindet sich die Datei _ViewStart.cshtml
im Ordner Pages (oder View). Die in _ViewStart.cshtml
aufgelisteten Anweisungen werden vor jeder vollständigen Ansicht (also keine Layouts und keine Teilansichten) ausgeführt. _ViewStart.cshtml
ist genauso wie ViewImports.cshtml hierarchisch. Wenn eine Datei namens _ViewStart.cshtml
im Ordner „View“ oder „Pages“ definiert wird, der mit einem Controller verknüpft ist, wird sie nach der Datei ausgeführt, die im Stamm des Ordners Pages (oder Views) definiert wurde (falls vorhanden).
Eine _ViewStart.cshtml
-Beispieldatei:
@{
Layout = "_Layout";
}
Die oben stehende Datei gibt an, dass alle Ansichten das _Layout.cshtml
-Layout verwenden.
_ViewStart.cshtml
und _ViewImports.cshtml
werden in der Regel nicht im Ordner /Pages/Shared (oder /Views/Shared) platziert. Die Versionen dieser Dateien auf Anwendungsebene sollten direkt in den Ordner /Pages (oder /Views) platziert werden.