Udostępnij za pomocą


Układ w ASP.NET Core

Przez Steve Smith i Dave Brock

Strony i widoki często udostępniają elementy wizualne i programowe. W tym artykule pokazano, jak:

  • Użyj typowych układów.
  • Udostępniaj dyrektywy.
  • Uruchom wspólny kod przed renderowaniem stron lub widoków.

W tym dokumencie omówiono układy dwóch różnych podejść do ASP.NET Core MVC: Razor strony i kontrolery z widokami. W tym temacie różnice są minimalne:

  • Razor Strony znajdują się w folderze Pages .
  • Kontrolery z widokami używają folderu Views dla widoków.

Co to jest układ

Większość aplikacji internetowych ma wspólny układ, który zapewnia użytkownikowi spójne środowisko podczas przechodzenia ze strony do strony. Układ zazwyczaj zawiera typowe elementy interfejsu użytkownika, takie jak nagłówek aplikacji, elementy nawigacji lub menu oraz stopka.

Przykład układu strony

Typowe struktury HTML, takie jak skrypty i arkusze stylów, są również często używane przez wiele stron w aplikacji. Wszystkie te elementy udostępnione można zdefiniować w pliku układu , do którego można się odwoływać przy użyciu dowolnego widoku używanego w aplikacji. Układy zmniejszają zduplikowany kod w widokach.

Zgodnie z konwencją domyślny układ aplikacji ASP.NET Core nosi nazwę _Layout.cshtml. Pliki układu dla nowych projektów ASP.NET Core utworzonych za pomocą szablonów to:

  • Razor Stron: Pages/Shared/_Layout.cshtml

    Folder Pages w Eksploratorze rozwiązań

  • Kontroler z widokami: Views/Shared/_Layout.cshtml

    Folder Views w Eksploratorze rozwiązań

Układ definiuje szablon najwyższego poziomu dla widoków w aplikacji. Aplikacje nie wymagają układu. Aplikacje mogą definiować więcej niż jeden układ z różnymi widokami określającymi różne układy.

Poniższy kod przedstawia plik układu dla utworzonego projektu szablonu z kontrolerem i widokami:

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

Określanie układu

Razor widoki mają Layout właściwość. Poszczególne widoki określają układ, ustawiając tę właściwość:

@{
    Layout = "_Layout";
}

Określony układ może używać pełnej ścieżki (na przykład /Pages/Shared/_Layout.cshtml lub /Views/Shared/_Layout.cshtml) lub częściowej nazwy (na przykład: _Layout). Gdy podana jest częściowa nazwa, Razor silnik widoku wyszukuje plik układu za pomocą swojego standardowego procesu odnajdywania. Najpierw przeszukiwany jest folder, w którym istnieje metoda obsługi (lub kontroler), a następnie folder Udostępniony . Ten proces odnajdywania jest identyczny z procesem używanym do odnajdywania widoków częściowych.

Domyślnie każdy układ musi wywoływać metodę RenderBody. Wszędzie tam, gdzie zostanie umieszczone wywołanie RenderBody , zawartość widoku zostanie wyrenderowana.

Sekcje

Układ może opcjonalnie odwoływać się do co najmniej jednej sekcji, wywołując metodę RenderSection. Sekcje umożliwiają organizowanie miejsc, w których należy umieścić określone elementy strony. Każda operacja RenderSection może określać, czy ta sekcja jest wymagana, czy opcjonalna.

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

@RenderSection("Scripts", required: false)

Jeśli wymagana sekcja nie zostanie znaleziona, zostanie zgłoszony wyjątek. Poszczególne widoki określają zawartość, która ma być renderowana w sekcji przy użyciu @sectionRazor składni. Jeśli strona lub widok definiuje sekcję, musi być renderowana (lub wystąpi błąd).

Przykładowa @section definicja w Razor widoku strony:

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

W poprzednim kodzie scripts/main.js jest dodawany do sekcji scripts na stronie lub widoku. Inne strony lub widoki w tej samej aplikacji mogą nie wymagać tego skryptu i nie zdefiniują sekcji skryptów.

Poniższy znacznik używa Partial Tag Helper do renderowania _ValidationScriptsPartial.cshtml:

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

Powyższy znacznik został wygenerowany przez szkieletowanie Identity.

Sekcje zdefiniowane na stronie lub widoku są dostępne tylko na stronie układu bezpośredniego. Nie można odwoływać się do nich z elementów częściowych, komponentów widoku ani innych elementów systemu widoków.

Ignorowanie sekcji

Domyślnie treść i wszystkie sekcje na stronie zawartości muszą być renderowane przez stronę układu. Silnik Razor widoku wymusza to, śledząc, czy treść i każda sekcja zostały renderowane.

Aby poinstruować silnik widoku, aby zignorował treść lub sekcje, wywołaj metody IgnoreBody i IgnoreSection.

Treść i każda sekcja na Razor stronie muszą być renderowane lub ignorowane.

Importowanie dyrektyw udostępnionych

Widoki i strony mogą używać Razor dyrektyw do importowania przestrzeni nazw i używania iniekcji zależności. Dyrektywy współużytkowane przez wiele widoków mogą być określone we wspólnym _ViewImports.cshtml pliku. Plik _ViewImports obsługuje następujące dyrektywy:

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

Plik nie obsługuje innych Razor funkcji, takich jak funkcje i definicje sekcji.

Przykładowy _ViewImports.cshtml plik:

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

Plik _ViewImports.cshtml aplikacji MVC platformy ASP.NET Core jest zwykle umieszczany w folderze Pages (lub Views). Plik _ViewImports.cshtml można umieścić w dowolnym folderze, w takim przypadku będzie on stosowany tylko do stron lub widoków w tym folderze i jego podfolderach. _ViewImports pliki są przetwarzane począwszy od poziomu głównego, a następnie dla każdego folderu prowadzącego do lokalizacji strony lub samego widoku. _ViewImports ustawienia określone na poziomie głównym mogą zostać zastąpione na poziomie folderu.

Załóżmy na przykład:

  • Plik poziomu _ViewImports.cshtml zawiera @model MyModel1 oraz @addTagHelper *, MyTagHelper1.
  • Plik w podfolderze _ViewImports.cshtml zawiera @model MyModel2 i @addTagHelper *, MyTagHelper2.

Strony i widoki w podfolderze będą miały dostęp zarówno do pomocników tagów, jak i do modelu MyModel2.

Jeśli w hierarchii plików znajduje się wiele _ViewImports.cshtml plików, połączone zachowanie dyrektyw to:

  • @addTagHelper, @removeTagHelper: wszystkie uruchomienia, w kolejności
  • @tagHelperPrefix: ten najbliższy widokowi ma pierwszeństwo przed innymi
  • @model: ten najbliższy widokowi nadpisuje wszystkie inne
  • @inherits: ten najbliżej widoku zastępuje wszystkie pozostałe
  • @using: wszystkie są uwzględnione; duplikaty są ignorowane
  • @inject: dla każdej właściwości, ta najbliższa widokowi zastępuje wszystkie inne z tą samą nazwą właściwości

Uruchamianie kodu przed każdym widokiem

Kod, który należy uruchomić przed każdym widokiem lub stroną, powinien zostać umieszczony w _ViewStart.cshtml pliku. Zgodnie z konwencją _ViewStart.cshtml plik znajduje się w folderze Pages (lub Views). Instrukcje wymienione w pliku _ViewStart.cshtml są uruchamiane przed każdym pełnym widokiem (nie układami, a nie częściowymi widokami). Podobnie jak ViewImports.cshtml, _ViewStart.cshtml jest hierarchiczny. _ViewStart.cshtml Jeśli plik jest zdefiniowany w folderze widoku lub stron, zostanie on uruchomiony po tym, jak został zdefiniowany w folderze głównym folderu Pages (lub Widoki) (jeśli istnieje).

Przykładowy _ViewStart.cshtml plik:

@{
    Layout = "_Layout";
}

Powyższy plik określa, że wszystkie widoki będą używać _Layout.cshtml układu.

_ViewStart.cshtml i _ViewImports.cshtmlnie są zwykle umieszczane w folderze /Pages/Shared (lub /Views/Shared). Wersje tych plików na poziomie aplikacji powinny zostać umieszczone bezpośrednio w folderze /Pages (lub /Views).