Layout in ASP.NET CoreLayout in ASP.NET Core

Von Steve Smith und Dave BrockBy Steve Smith and Dave Brock

Seiten und Ansichten beinhalten häufig sowohl visuelle als auch programmgesteuerte Elemente.Pages and views frequently share visual and programmatic elements. Dieser Artikel demonstriert Folgendes:This article demonstrates how to:

  • Verwendung von allgemeinen LayoutsUse common layouts.
  • Freigeben von AnweisungenShare directives.
  • Führen Sie den allgemeinen Code aus, bevor Sie Seiten oder Ansichten rendern.Run common code before rendering pages or views.

In diesem Dokument werden die Layouts für die beiden unterschiedlichen Ansätze zum ASP.net Core MVC erläutert: Razor Seiten und Controller mit Ansichten.This document discusses layouts for the two different approaches to ASP.NET Core MVC: Razor Pages and controllers with views. In diesem Thema sind die Unterschiede minimal:For this topic, the differences are minimal:

  • RazorSeiten befinden sich im Ordner pages . Pages are in the Pages folder.
  • Controller mit Ansichten verwenden einen Ordner namens Views für Ansichten.Controllers with views uses a Views folder for views.

Was ist ein Layout?What is a Layout

Die meisten Web-Apps haben ein gebräuchliches Layout, das dem Benutzer beim Navigieren auf den Seiten ein konsistentes Verhalten bietet.Most web apps have a common layout that provides the user with a consistent experience as they navigate from page to page. Das Layout enthält normalerweise allgemeine Benutzeroberflächenelemente wie App-Header, Navigations- oder Menüelemente sowie eine Fußzeile.The layout typically includes common user interface elements such as the app header, navigation or menu elements, and footer.

Beispiel für ein Seitenlayout

Gängige HTML-Strukturen wie Skripts und Stylesheets werden häufig von vielen Seiten in einer App verwendet.Common HTML structures such as scripts and stylesheets are also frequently used by many pages within an app. Alle diese gemeinsamen Elemente werden in einer Layoutdatei definiert, auf die dann von jeder Ansicht einer App verwiesen werden kann.All of these shared elements may be defined in a layout file, which can then be referenced by any view used within the app. Layouts minimieren duplizierten Code in Ansichten.Layouts reduce duplicate code in views.

Gemäß Konvention ist _Layout.cshtml das Standardlayout für eine ASP.NET Core-App.By convention, the default layout for an ASP.NET Core app is named _Layout.cshtml. Für neue ASP.NET Core-Projekte, die mit den Vorlagen erstellt wurden, sind folgende Layoutdateien vorhanden:The layout files for new ASP.NET Core projects created with the templates are:

  • RazorSeiten: pages/Shared/_Layout. cshtml Pages: Pages/Shared/_Layout.cshtml

    Ordner „Pages“ im Projektmappen-Explorer

  • Controller mit Ansichten: Views/Shared/_Layout.cshtmlController with views: Views/Shared/_Layout.cshtml

    Ordner „Views“ im Projektmappen-Explorer

Das Layout definiert eine übergeordnete Vorlage für die Ansichten einer App.The layout defines a top level template for views in the app. Apps erfordern nicht zwingend ein Layout.Apps don't require a layout. Apps können aber auch mehrere Layouts definieren. Die Ansichten der App können dann unterschiedliche Layouts nutzen.Apps can define more than one layout, with different views specifying different layouts.

Der folgende Code zeigt die Layoutdatei für eine Vorlage, die mit dem Projekt mit einem Controller und Ansichten erstellt wurde:The following code shows the layout file for a template created project with a controller and views:

<!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>

Festlegen eines LayoutsSpecifying a Layout

RazorSichten verfügen über eine- Layout Eigenschaft. views have a Layout property. Durch Festlegen dieser Eigenschaft wird das Layout der jeweiligen Ansicht bestimmt:Individual views specify a layout by setting this property:

@{
    Layout = "_Layout";
}

Das angegebene Layout kann einen vollständigen Pfad (z.B. /Pages/Shared/_Layout.cshtml oder /Views/Shared/_Layout.cshtml) oder einen Teil des Namens (Beispiel: _Layout) aufweisen.The layout specified can use a full path (for example, /Pages/Shared/_Layout.cshtml or /Views/Shared/_Layout.cshtml) or a partial name (example: _Layout). Wenn ein partieller Name angegeben wird, Razor sucht die Ansichts-Engine mithilfe Ihres Standard Ermittlungs Prozesses nach der Layoutdatei.When a partial name is provided, the Razor view engine searches for the layout file using its standard discovery process. Der Ordner, in dem sich die die Handlermethode (oder der Controller) befindet, wird zuerst durchsucht und danach der Ordner Shared.The folder where the handler method (or controller) exists is searched first, followed by the Shared folder. Dieser Ermittlungsprozess ist identisch mit dem Prozess zum Auffinden von Teilansichten.This discovery process is identical to the process used to discover partial views.

Standardmäßig muss jedes Layout RenderBody aufrufen.By default, every layout must call RenderBody. Wo immer der Aufruf von RenderBody platziert ist, wird der Inhalt der Ansicht gerendert.Wherever the call to RenderBody is placed, the contents of the view will be rendered.

AbschnitteSections

Optional kann ein Layout auf mindestens einen Abschnitt verweisen, indem es RenderSection aufruft.A layout can optionally reference one or more sections, by calling RenderSection. Abschnitte geben an, wo bestimmte Seitenelemente platziert werden sollen.Sections provide a way to organize where certain page elements should be placed. Jeder Aufruf von RenderSection kann angeben, ob dieser Abschnitt erforderlich ist:Each call to RenderSection can specify whether that section is required or optional:

<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.If a required section isn't found, an exception is thrown. Einzelne Ansichten geben den Inhalt an, der in einem Abschnitt mithilfe der Syntax gerendert werden soll @section Razor .Individual views specify the content to be rendered within a section using the @section Razor syntax. Wenn eine Seite oder eine Ansicht einen Abschnitt definiert, muss dieser auch gerendert werden. Andernfalls tritt ein Fehler auf.If a page or view defines a section, it must be rendered (or an error will occur).

Eine Beispiel @section Definition in der Razor Seitenansicht:An example @section definition in Razor Pages view:

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

Im vorangehenden Code wird scripts/main.js zum Abschnitt scripts auf einer Seite oder in einer Ansicht hinzugefügt.In the preceding code, scripts/main.js is added to the scripts section on a page or view. Andere Seiten oder Ansichten in der gleichen App benötigen dieses Skript möglicherweise nicht und definieren einen Abschnitt zu Skripts.Other pages or views in the same app might not require this script and wouldn't define a scripts section.

In der folgenden Markupdatei wird die Datei _ValidationScriptsPartial.cshtml mit dem Partial-Taghilfsprogramm gerendert:The following markup uses the Partial Tag Helper to render _ValidationScriptsPartial.cshtml:

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

Das vorangehende Markup wurde durch Identity Gerüstbau generiert.The preceding markup was generated by scaffolding Identity.

Die Abschnitte, die auf einer Seite oder in einer Ansicht definiert wurden, stehen nur auf deren Layoutseite zur Verfügung.Sections defined in a page or view are available only in its immediate layout page. Teilansichten, Ansichtskomponenten und andere Teile eines Ansichtssystems können nicht auf sie verweisen.They cannot be referenced from partials, view components, or other parts of the view system.

Ignorieren von AbschnittenIgnoring sections

Standardmäßig müssen der Text und die Abschnitte einer Inhaltsseite alle von der Layoutseite gerendert werden.By default, the body and all sections in a content page must all be rendered by the layout page. Die Razor Ansichts-Engine erzwingt dies durch nachverfolgen, ob der Text und jeder Abschnitt gerendert wurden.The Razor view engine enforces this by tracking whether the body and each section have been rendered.

Rufen Sie die Methoden IgnoreBody und IgnoreSection auf, um die Ansichtsengine anzuweisen, den Text oder die Abschnitte zu ignorieren.To instruct the view engine to ignore the body or sections, call the IgnoreBody and IgnoreSection methods.

Der Text und jeder Abschnitt einer Razor Seite müssen entweder gerendert oder ignoriert werden.The body and every section in a Razor page must be either rendered or ignored.

Importieren gemeinsam verwendeter AnweisungenImporting Shared Directives

Sichten und Seiten können Razor -Direktiven verwenden, um Namespaces zu importieren und Abhängigkeitsinjektionzu verwenden.Views and pages can use Razor directives to import namespaces and use dependency injection. Anweisungen, die von mehreren Ansichten gemeinsam verwendet werden, können in einer gemeinsam verwendeten Datei namens _ViewImports.cshtml angegeben werden.Directives shared by many views may be specified in a common _ViewImports.cshtml file. Die _ViewImports-Datei unterstützt die folgenden Anweisungen:The _ViewImports file supports the following directives:

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

Die Datei unterstützt keine anderen Razor Features, wie z. b. Funktionen und Abschnitts Definitionen.The file doesn't support other Razor features, such as functions and section definitions.

Eine _ViewImports.cshtml-Beispieldatei:A sample _ViewImports.cshtml file:

@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).The _ViewImports.cshtml file for an ASP.NET Core MVC app is typically placed in the Pages (or Views) folder. Eine Datei _ViewImports.cshtml kann auch in einen anderen Ordner verschoben werden. In diesem Fall wird sie nur auf die Seiten oder Ansichten in diesem Ordner und in dessen Unterordnern angewendet.A _ViewImports.cshtml file can be placed within any folder, in which case it will only be applied to pages or views within that folder and its subfolders. _ViewImports-Dateien werden beginnend ab der Stammebene verarbeitet und dann einzeln für jeden Ordner bis zum Speicherort der Seite oder der Ansicht selbst._ViewImports files are processed starting at the root level and then for each folder leading up to the location of the page or view itself. Die _ViewImports-Einstellungen auf der Stammebene werden möglicherweise auf Ordnerebene außer Kraft gesetzt._ViewImports settings specified at the root level may be overridden at the folder level.

Nehmen Sie beispielsweise Folgendes an:For example, suppose:

  • Die Datei _ViewImports.cshtml auf der Stammebene enthält @model MyModel1 und @addTagHelper *, MyTagHelper1.The root level _ViewImports.cshtml file includes @model MyModel1 and @addTagHelper *, MyTagHelper1.
  • Die Datei _ViewImports.cshtml in einem Unterordner enthält @model MyModel2 und @addTagHelper *, MyTagHelper2.A subfolder _ViewImports.cshtml file includes @model MyModel2 and @addTagHelper *, MyTagHelper2.

Seiten und Ansichten im Unterordner haben Zugriff auf beide Taghilfsprogramme und das Modell MyModel2.Pages and views in the subfolder will have access to both Tag Helpers and the MyModel2 model.

Wenn sich mehrere Dateien namens _ViewImports.cshtml in der Hierarchie befinden, umfasst das kombinierte Verhalten der Anweisungen Folgendes:If multiple _ViewImports.cshtml files are found in the file hierarchy, the combined behavior of the directives are:

  • @addTagHelper, @removeTagHelper: werden nach der Reihe ausgeführt@addTagHelper, @removeTagHelper: all run, in order
  • @tagHelperPrefix: dasjenige, das der Ansicht am Nächsten ist, setzt die anderen außer Kraft@tagHelperPrefix: the closest one to the view overrides any others
  • @model: dasjenige, das der Ansicht am Nächsten ist, setzt die anderen außer Kraft@model: the closest one to the view overrides any others
  • @inherits: dasjenige, das der Ansicht am Nächsten ist, setzt die anderen außer Kraft@inherits: the closest one to the view overrides any others
  • @using: alle einbezogen; Duplikate werden ignoriert@using: all are included; duplicates are ignored
  • @inject: dasjenige, das der Ansicht am Nächsten ist, setzt für jede Eigenschaft alle anderen mit dem gleichen Namen außer Kraft@inject: for each property, the closest one to the view overrides any others with the same property name

Ausführen von Code vor jeder AnsichtRunning Code Before Each View

Code, der ausgeführt werden muss, bevor die einzelnen Ansichten oder Seiten in die Datei _ViewStart.cshtml platziert werden.Code that needs to run before each view or page should be placed in the _ViewStart.cshtml file. Gemäß der Konvention befindet sich die Datei _ViewStart.cshtml im Ordner Seiten (oder Ansichten).By convention, the _ViewStart.cshtml file is located in the Pages (or Views) folder. Die in _ViewStart.cshtml aufgelisteten Anweisungen werden vor jeder vollständigen Ansicht (also keine Layouts und keine Teilansichten) ausgeführt.The statements listed in _ViewStart.cshtml are run before every full view (not layouts, and not partial views). _ViewStart.cshtml ist genauso wie ViewImports.cshtml hierarchisch.Like ViewImports.cshtml, _ViewStart.cshtml is hierarchical. Wenn eine Datei namens _ViewStart.cshtml im Ordner „Ansichten“ oder „Seiten“, der mit einem Controller verknüpft ist, definiert wird, wird sie nach derjenigen ausgeführt, die im Stamm des Ordners Seiten (oder Ansichten) definiert wurde (falls vorhanden).If a _ViewStart.cshtml file is defined in the view or pages folder, it will be run after the one defined in the root of the Pages (or Views) folder (if any).

Ein Beispiel für die Datei _ViewStart.cshtml:A sample _ViewStart.cshtml file:

@{
    Layout = "_Layout";
}

Die oben stehende Datei gibt an, dass alle Ansichten das Layout _Layout.cshtml verwenden.The file above specifies that all views will use the _Layout.cshtml layout.

_ViewStart.cshtml und _ViewImports.cshtml werden in der Regel nicht in den Ordner /Pages/Shared (oder * /Views/Shared*) platziert._ViewStart.cshtml and _ViewImports.cshtml are not typically placed in the /Pages/Shared (or /Views/Shared) folder. Die Versionen dieser Dateien auf Anwendungsebene sollten direkt in den Ordner /Pages (oder /Views) platziert werden.The app-level versions of these files should be placed directly in the /Pages (or /Views) folder.