Layout i ASP.NET Core

Av Steve Smith och Dave Brock

Sidor och vyer delar ofta visuella och programmatiska element. Den här artikeln visar hur du:

  • Använd vanliga layouter.
  • Dela instruktioner.
  • Kör vanlig kod innan du återger sidor eller vyer.

I det här dokumentet beskrivs layouter för de två olika tillvägagångssätten för ASP.NET Core MVC: Razor Sidor och controllers med vyer. För det här avsnittet är skillnaderna minimala:

  • Razor Sidorna finns i mappen Sidor .
  • Kontrollanter med vyer använder en views-mapp för vyer.

Vad är en layout

De flesta webbappar har en gemensam layout som ger användaren en konsekvent upplevelse när de navigerar från sida till sida. Layouten innehåller vanligtvis vanliga användargränssnittselement som apprubrik, navigerings- eller menyelement och sidfot.

Exempel på sidlayout

Vanliga HTML-strukturer som skript och formatmallar används också ofta av många sidor i en app. Alla dessa delade element kan definieras i en layoutfil , som sedan kan refereras till av alla vyer som används i appen. Layouter minskar duplicerad kod i vyer.

Standardlayouten för en ASP.NET Core-app heter _Layout.cshtmlenligt konventionen . Layoutfilerna för nya ASP.NET Core-projekt som skapats med mallarna är:

  • Razor Sidor: Pages/Shared/_Layout.cshtml

    Pages-mappen i Solution Explorer

  • Kontrollant med vyer: Views/Shared/_Layout.cshtml

    Visar mappen i Solution Explorer

Layouten definierar en mall på den översta nivån för vyer i appen. Appar kräver ingen layout. Appar kan definiera mer än en layout med olika vyer som anger olika layouter.

Följande kod visar layoutfilen för ett projekt skapat från en mall med en kontroller och vyer.

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

Ange en layout

Razor vyer har en Layout egenskap. Enskilda vyer anger en layout genom att ange den här egenskapen:

@{
    Layout = "_Layout";
}

Den angivna layouten kan använda en fullständig sökväg (till exempel /Pages/Shared/_Layout.cshtml eller /Views/Shared/_Layout.cshtml) eller ett partiellt namn (exempel: _Layout). När ett partiellt namn anges Razor söker vymotorn efter layoutfilen med hjälp av dess standardidentifieringsprocess. Mappen där hanteringsmetoden (eller kontrollanten) finns genomsöks först, följt av den delade mappen. Den här identifieringsprocessen är identisk med den process som används för att identifiera partiella vyer.

Som standard måste varje layout anropa RenderBody. Oavsett var anropet till RenderBody görs återges innehållet i vyn.

Sektioner

En layout kan också referera till ett eller flera avsnitt genom att anropa RenderSection. Avsnitt ger en struktur för hur vissa sidans element ska placeras. Varje anrop till RenderSection kan ange om det avsnittet är obligatoriskt eller valfritt:

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

@RenderSection("Scripts", required: false)

Om ett obligatoriskt avsnitt inte hittas utlöses ett undantag. Enskilda vyer anger det innehåll som ska återges i ett avsnitt med hjälp av syntaxen @sectionRazor . Om en sida eller vy definierar ett avsnitt måste det återges (eller så uppstår ett fel).

Ett exempel på en definition @section i sidvyn Razor:

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

I föregående kod scripts/main.js läggs till i scripts avsnittet på en sida eller vy. Andra sidor eller vyer i samma app kanske inte kräver det här skriptet och definierar inte ett skriptavsnitt.

Följande kod använder hjälpverktyget för partiell tagg för att återge _ValidationScriptsPartial.cshtml:

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

Föregående markering genererades av scaffolding Identity.

Avsnitt som definierats i en sida eller vy är endast tillgängliga på den omedelbara layoutsidan. De kan inte refereras från delar, visa komponenter eller andra delar av visningssystemet.

Ignorera avsnitt

Som standard måste brödtexten och alla avsnitt på en innehållssida återges av layoutsidan. Vymotorn Razor framtvingar detta genom att spåra om brödtexten och varje avsnitt har renderats.

Anropa metoderna IgnoreBody och IgnoreSection för att instruera vy-motorn att ignorera brödtexten eller avsnitten.

Brödtexten och varje avsnitt på en Razor sida måste antingen återges eller ignoreras.

Importera gemensamma direktiv

Vyer och sidor kan använda Razor direktiv för att importera namnområden och använda beroendeinmatning. Direktiv som delas av många vyer kan anges i en gemensam _ViewImports.cshtml-fil. Filen _ViewImports stöder följande direktiv:

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

Filen stöder inte andra Razor funktioner, till exempel funktioner och avsnittsdefinitioner.

En exempelfil _ViewImports.cshtml :

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

Filen _ViewImports.cshtml för en ASP.NET Core MVC-app placeras vanligtvis i mappen Pages (eller Views). En _ViewImports.cshtml fil kan placeras i valfri mapp, i så fall tillämpas den endast på sidor eller vyer i mappen och dess undermappar. _ViewImports filer bearbetas från och med rotnivån och sedan för varje mapp som leder upp till platsen för sidan eller själva vyn. _ViewImports inställningar som anges på rotnivå kan åsidosättas på mappnivå.

Anta till exempel:

  • Rotnivåfilen _ViewImports.cshtml innehåller @model MyModel1 och @addTagHelper *, MyTagHelper1.
  • En undermappsfil _ViewImports.cshtml innehåller @model MyModel2 och @addTagHelper *, MyTagHelper2.

Sidor och vyer i undermappen har åtkomst till både Tag Helpers och MyModel2 modellen.

Om flera _ViewImports.cshtml filer hittas i filhierarkin är det kombinerade beteendet för direktiven:

  • @addTagHelper, @removeTagHelper: körs alla i ordning
  • @tagHelperPrefix: den närmaste till vyn åsidosätter alla andra
  • @model: den närmaste i vyn åsidosätter alla andra
  • @inherits: den närmaste till vyn åsidosätter alla andra
  • @using: alla ingår; dubbletter ignoreras
  • @inject: För varje egenskap åsidosätter den egenskap som är närmast vyn alla andra med samma egenskapsnamn

Köra kod före varje visning

Kod som måste köras innan varje vy eller sida ska placeras i _ViewStart.cshtml filen. Enligt konventionen _ViewStart.cshtml finns filen i mappen Pages (eller Views). De instruktioner som anges i _ViewStart.cshtml körs före varje fullständig vy (inte layouter och inte partiella vyer). Precis som ViewImports.cshtml_ViewStart.cshtml är hierarkisk. Om en _ViewStart.cshtml fil definieras i vyn eller sidmappen körs den efter den som definierats i roten för mappen Pages (eller Views) (om någon).

En exempelfil _ViewStart.cshtml :

@{
    Layout = "_Layout";
}

Filen ovan anger att alla vyer ska använda layouten _Layout.cshtml .

_ViewStart.cshtml och _ViewImports.cshtml placeras vanligtvis inte i mappen /Pages/Shared (eller /Views/Shared). Appnivåversionerna av dessa filer ska placeras direkt i mappen /Pages (eller /Views).