Freigeben über


Layout in ASP.NET Core

Von Steve Smith und Dave Brock

Seiten und Ansichten teilen häufig visuelle und programmgesteuerte Elemente. Dieser Artikel demonstriert Folgendes:

  • Verwenden Sie allgemeine Layouts.
  • Freigabedirektiven.
  • Führen Sie allgemeinen Code vor dem Rendern von Seiten oder Ansichten aus.

In diesem Dokument werden Layouts für die beiden verschiedenen Ansätze für ASP.NET Core MVC erläutert: Razor Seiten und Controller mit Ansichten. Für dieses Thema sind die Unterschiede minimal:

  • Razor Seiten befinden sich im Ordner "Seiten" .
  • Controller mit Ansichten verwenden einen Ansichtenordner für Ansichten.

Was ist ein Layout?

Die meisten Web-Apps verfügen über ein gemeinsames Layout, das dem Benutzer eine konsistente Benutzererfahrung bietet, während er von Seite zu Seite navigiert. Das Layout enthält in der Regel allgemeine Benutzeroberflächenelemente wie die App-Kopfzeile, navigations- oder Menüelemente und Fußzeile.

Beispiel für seitenlayout

Allgemeine HTML-Strukturen wie Skripts und Stylesheets werden auch häufig von vielen Seiten in einer App verwendet. Alle diese freigegebenen Elemente können in einer Layoutdatei definiert werden, auf die dann von jeder in der App verwendeten Ansicht verwiesen werden kann. Layouts reduzieren doppelten Code in Ansichten.

In der Konvention heißt _Layout.cshtmldas Standardlayout für eine ASP.NET Core-App. Die Layoutdateien für neue ASP.NET Core-Projekte, die mit den Vorlagen erstellt wurden, sind:

  • Razor Seiten: Pages/Shared/_Layout.cshtml

    Ordner

  • Controller mit Ansichten: Views/Shared/_Layout.cshtml

    Ordner

Das Layout definiert eine Vorlage auf oberster Ebene für Ansichten in der App. Apps benötigen kein Layout. Apps können mehrere Layouts definieren, wobei unterschiedliche Ansichten unterschiedliche Layouts angeben.

Der folgende Code zeigt die Layoutdatei für ein Vorlage-erstelltes Projekt mit einem Controller und Ansichten:

<!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>&copy; 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>

Angeben eines Layouts

Razor Ansichten verfügen über eine Layout Eigenschaft. Einzelne Ansichten geben ein Layout an, indem Sie diese Eigenschaft festlegen:

@{
    Layout = "_Layout";
}

Das angegebene Layout kann einen vollständigen Pfad (z. B. /Pages/Shared/_Layout.cshtml oder /Views/Shared/_Layout.cshtml) oder einen teilweisen Namen (Beispiel: _Layout) verwenden. Wenn ein Teilname angegeben wird, sucht das Razor Ansichtsmodul mithilfe seines standardmäßigen Ermittlungsprozesses nach der Layoutdatei. Der Ordner, in dem die Handlermethode (oder der Controller) vorhanden ist, wird zuerst durchsucht, gefolgt vom Ordner "Freigegeben" . Dieser Ermittlungsprozess ist identisch mit dem Prozess, der zum Ermitteln von Teilansichten verwendet wird.

Standardmäßig muss jedes Layout den Aufruf RenderBody enthalten. Wenn der Aufruf von RenderBody erfolgt, wird der Inhalt der Ansicht überall gerendert.

Abschnitte

Ein Layout kann optional auf einen oder mehrere Abschnitte verweisen, indem es RenderSection aufruft. Abschnitte bieten eine Möglichkeit zum Organisieren, wo bestimmte Seitenelemente platziert werden sollen. Jeder Aufruf RenderSection kann angeben, ob dieser Abschnitt erforderlich oder optional ist:

<script type="text/javascript" src="~/scripts/global.js"></script>

@RenderSection("Scripts", required: false)

Wenn ein erforderlicher Abschnitt nicht gefunden wird, wird eine Ausnahme ausgelöst. Einzelne Ansichten geben den Inhalt an, der in einem Abschnitt mithilfe der @sectionRazor Syntax gerendert werden soll. Wenn eine Seite oder Ansicht einen Abschnitt definiert, muss er gerendert werden (oder ein Fehler tritt auf).

@section Beispieldefinition in der Razor Seitenansicht:

@section Scripts {
     <script type="text/javascript" src="~/scripts/main.js"></script>
}

Im vorherigen Code wird scripts/main.js dem scripts Abschnitt auf einer Seite oder Ansicht hinzugefügt. Andere Seiten oder Ansichten in derselben App erfordern dieses Skript möglicherweise nicht und definieren keinen Skriptabschnitt.

Das folgende Markup verwendet den Partial Tag Helper, um _ValidationScriptsPartial.cshtml zu rendern:

@section Scripts {
    <partial name="_ValidationScriptsPartial" />
}

Das vorangehende Markup wurde durch Scaffolding Identitygeneriert.

Abschnitte, die in einer Seite oder Ansicht definiert sind, sind nur auf der unmittelbaren Layoutseite verfügbar. Sie können nicht aus Partials, View-Komponenten oder anderen Teilen des View-Systems referenziert werden.

Ignorieren von Abschnitten

Standardmäßig muss der Textkörper und alle Abschnitte auf einer Inhaltsseite von der Layoutseite gerendert werden. Das Razor Ansichtsmodul erzwingt dies, indem nachverfolgt wird, ob der Textkörper und jeder Abschnitt gerendert wurden.

Rufen Sie die Methoden IgnoreBody und IgnoreSection auf, um die View-Engine anzuweisen, den Body oder die Abschnitte zu ignorieren.

Der Textkörper und jeder Abschnitt einer Razor Seite müssen entweder gerendert oder ignoriert werden.

Importieren freigegebener Direktiven

Ansichten und Seiten können Razor-Direktiven verwenden, um Namespaces zu importieren und Dependency Injection zu verwenden. Richtlinien, die von vielen Ansichten gemeinsam genutzt werden, können in einer gemeinsamen _ViewImports.cshtml Datei angegeben werden. Die _ViewImports Datei unterstützt die folgenden Direktiven:

  • @addTagHelper
  • @removeTagHelper
  • @tagHelperPrefix
  • @using
  • @model
  • @inherits
  • @inject
  • @namespace

Die Datei unterstützt keine anderen Razor Features, z. B. Funktionen und Abschnittsdefinitionen.

Beispieldatei _ViewImports.cshtml :

@using WebApplication1
@using WebApplication1.Models
@using WebApplication1.Models.AccountViewModels
@using WebApplication1.Models.ManageViewModels
@using Microsoft.AspNetCore.Identity
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

Die _ViewImports.cshtml Datei für eine ASP.NET Core MVC-App wird in der Regel im Ordner "Seiten " (oder "Ansichten") platziert. Eine _ViewImports.cshtml Datei kann in einem beliebigen Ordner platziert werden, in diesem Fall wird sie nur auf Seiten oder Ansichten innerhalb dieses Ordners und seiner Unterordner angewendet. _ViewImports Dateien werden beginnend auf der Stammebene und dann für jeden Ordner verarbeitet, der zum Speicherort der Seite oder Ansicht selbst führt. _ViewImports Einstellungen, die auf der Root-Ebene angegeben sind, können auf Ordner-Ebene überschrieben werden.

Nehmen wir beispielsweise folgendes an:

  • Die Stammebenendatei _ViewImports.cshtml enthält @model MyModel1 und @addTagHelper *, MyTagHelper1.
  • Eine Unterordnerdatei _ViewImports.cshtml enthält @model MyModel2 und @addTagHelper *, MyTagHelper2.

Seiten und Ansichten im Unterordner haben auf die Tag-Helper und das MyModel2 Modell Zugriff.

Wenn mehrere _ViewImports.cshtml Dateien in der Dateihierarchie gefunden werden, sind die kombinierten Verhaltensweisen der Direktiven:

  • @addTagHelper, @removeTagHelper alle ausgeführt, in der Reihenfolge
  • @tagHelperPrefix: Der Ansicht am nächsten kommende setzt alle anderen außer Kraft
  • @model: Der der Ansicht am nächsten gelegene hat Vorrang vor allen anderen
  • @inherits: Die dem Blick nächstgelegene Einstellung hebt alle anderen auf.
  • @using: alle sind enthalten; Duplikate werden ignoriert.
  • @inject: Für jede Eigenschaft überschreibt die der Ansicht am nächsten ist alle anderen mit demselben Eigenschaftsnamen.

Ausführen von Code vor jeder Ansicht

Code, der ausgeführt werden muss, bevor jede Ansicht oder Seite in der _ViewStart.cshtml Datei platziert werden soll. Üblicherweise befindet sich die _ViewStart.cshtml-Datei im Ordner „Seiten“ (oder „Ansichten“). Die darin _ViewStart.cshtml aufgeführten Anweisungen werden vor jeder Vollansicht ausgeführt (keine Layouts und keine Teilansichten). Wie ViewImports.cshtml ist _ViewStart.cshtml hierarchisch. Wenn eine _ViewStart.cshtml Datei im Ordner "Ansicht" oder "Seiten" definiert ist, wird sie nach dem im Stammverzeichnis des Ordners "Seiten " (oder "Ansichten") (falls vorhanden) definierten Datei ausgeführt.

Beispieldatei _ViewStart.cshtml :

@{
    Layout = "_Layout";
}

Die obige 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) abgelegt. Die Versionen dieser Dateien auf App-Ebene sollten direkt im Ordner /Pages (oder /Views) platziert werden.