共用方式為


ASP.NET 核心區的佈局

作者:Steve SmithDave Brock

頁面與檢視經常共享視覺與程式元素。 本文會示範如何:

  • 使用常見的版面配置。
  • 分享指令。
  • 在渲染頁面或檢視前,先執行常用程式碼。

本文件討論了 ASP.NET Core MVC 的兩種不同方法的佈局:Razor Pages 和帶有視圖的控制器。 在這個主題上,差異很小:

  • Razor 頁面在 Pages 資料夾裡。
  • 有視圖的控制器會用 Views 資料夾來存放視圖。

什麼是佈局

大多數網頁應用程式都有共通的版面配置,讓使用者在瀏覽頁面時能有一致的體驗。 版面配置通常包含常見的使用者介面元素,如應用程式標頭、導覽或選單元素,以及頁尾。

頁面佈局範例

常見的 HTML 結構,如腳本和樣式表,也經常被應用程式內的多個頁面使用。 所有這些共享元素都可以定義在 版面 檔案中,接著該應用程式內任何檢視都可以參考該檔案。 版面配置能減少檢視中重複的程式碼。

依慣例,ASP.NET Core 應用程式的預設版面稱為 _Layout.cshtml。 使用這些範本建立的新 ASP.NET Core 專案的版面檔案如下:

  • Razor 頁數: Pages/Shared/_Layout.cshtml

    方案總管中的 Pages 資料夾

  • 控制器與視圖:Views/Shared/_Layout.cshtml

    解決方案總管中的 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>

指定佈局

Razor 視圖具有屬性 Layout 。 個別視圖透過設定以下屬性來指定版面:

@{
    Layout = "_Layout";
}

指定的版面配置可以使用完整路徑(例如, /Pages/Shared/_Layout.cshtml/Views/Shared/_Layout.cshtml)或部分名稱(例如: _Layout)。 當提供部分名稱時, Razor 檢視引擎會使用標準的發現程序搜尋該版面檔案。 首先搜尋包含處理器方法(或控制器)的資料夾,接著是 Shared 資料夾。 此發現過程與發現 部分視圖的過程相同。

預設情況下,每個佈局都必須呼叫 RenderBody。 不論在何處呼叫函式RenderBody,視圖內容都會被呈現。

章節

版面配置可選擇性地參考一個或多個 區段,方法是呼叫 RenderSection。 章節提供了組織特定頁面元素應放置位置的方法。 每次呼叫 RenderSection 都可以指定該區段是必須還是可選:

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

@RenderSection("Scripts", required: false)

若找不到必填區段,則會拋出例外。 個別檢視會根據語 @sectionRazor 法指定在某區段內要呈現的內容。 如果頁面或檢視定義了一個區段,必須渲染(否則會發生錯誤)。

頁面檢視中的@section範例Razor定義:

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

在前述程式碼中,scripts/main.js 被加入 scripts 的頁面或檢視區段。 同一應用程式中的其他頁面或檢視可能不需要這個腳本,也不會定義腳本區塊。

以下標記使用 部分標籤輔助 器來渲染 _ValidationScriptsPartial.cshtml

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

前述的標記是透過 支架 Identity產生的。

頁面或檢視中定義的區段僅在其直接版面頁面中可用。 它們無法從部分視圖、視圖元件或視圖系統的其他部分中被引用。

忽略部分

預設情況下,內容頁的正文及所有區段必須由版面頁面渲染。 Razor視圖引擎會透過追蹤內文和每個區段是否已渲染來強制執行此機制。

若要指示視圖引擎忽略主體或區段,請呼叫 IgnoreBodyIgnoreSection 方法。

頁面的正文和每個區塊 Razor 必須被渲染或忽略。

匯入共享指令集

檢視與頁面可以使用 Razor 指令來匯入命名空間並使用 依賴注入。 多個視圖共享的指令可在共用 _ViewImports.cshtml 檔案中指定。 該 _ViewImports 檔案支援以下指令:

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

該檔案不支援其他 Razor 功能,例如函式和區段定義。

範例 _ViewImports.cshtml 檔案:

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

ASP.NET Core MVC 應用程式的 _ViewImports.cshtml 檔案通常會放在 Pages (或 Views)資料夾中。 _ViewImports.cshtml檔案可以放置在任何資料夾中,此時只會套用到該資料夾及其子資料夾內的頁面或檢視。 _ViewImports 檔案從根級開始處理,然後依序處理每個資料夾,直到頁面或檢視本身的位置。 _ViewImports 根層級指定的設定可在資料夾層級被覆寫。

例如,假設:

  • 根層 _ViewImports.cshtml 檔案包含 @model MyModel1@addTagHelper *, MyTagHelper1
  • 子資料夾 _ViewImports.cshtml 檔案包含 @model MyModel2@addTagHelper *, MyTagHelper2

子資料夾中的頁面和檢視將同時存取標籤輔助工具和模型。MyModel2

若檔案階層中存在多個 _ViewImports.cshtml 檔案,指令的綜合行為如下:

  • @addTagHelper@removeTagHelper:全部執行,依序
  • @tagHelperPrefix:距離視圖最近的會覆蓋其他所有
  • @model:最接近視圖的將會覆蓋其他所有選項。
  • @inherits:最接近視圖的物件會覆蓋其他所有
  • @using:全部包含;重複者則被忽略
  • @inject:對於每個屬性,最接近該視圖的物件會覆蓋所有擁有相同屬性名稱的其他物件

在每個檢視前執行程式碼

需要在每個檢視或頁面之前執行的程式碼,應該放在檔案中 _ViewStart.cshtml 。 依慣例,檔案 _ViewStart.cshtml 位於 Pages (或 Views)資料夾中。 這些 _ViewStart.cshtml 陳述會在每個完整檢視之前執行(不是版面配置,也不是部分檢視)。 像 ViewImports.cshtml 一樣, _ViewStart.cshtml 是階層式的。 如果檔案 _ViewStart.cshtml 在 View 或 Pages 資料夾中定義,該檔案會在 Pages (或 Views)資料夾根目錄中定義的檔案(若有的話)之後執行。

範例 _ViewStart.cshtml 檔案:

@{
    Layout = "_Layout";
}

上述檔案指定所有視圖都會使用該 _Layout.cshtml 版面配置。

_ViewStart.cshtml_ViewImports.cshtml通常不會放在/Pages/Shared(或/Views/Shared)資料夾中。 這些檔案的應用程式層級版本應直接放在 /Pages (或 /Views)資料夾中。