ASP.NET Core 中文文檔 第四章 MVC(3.3)布局視圖


原文:Layout
作者:Steve Smith
翻譯:婁宇(Lyrics)
校對:孟帥洋(書緣)

視圖(View)經常共享視覺元素和編程元素。在本篇文章中,你將學習如何在你的 ASP.NET 應用程序中使用通用布局視圖、共享指令以及在渲染視圖前運行通用代碼。

章節:

什么是布局視圖

大部分 Web 應用程序在用戶切換頁面時,使用通用布局提供了一致的用戶體驗。通用布局通常包含頁眉、導航欄(或菜單)以及頁腳等通用 UI 元素。

在一個應用程序中,諸如腳本(scripts)和樣式表(stylesheets)這樣的通用 HTML 結構也頻繁的被許多頁面使用。所有的這些共享元素可以在 layout 文件中定義,這樣應用程序中的任何視圖都可以使用它們。布局視圖減少了視圖中的重復代碼,幫助我們遵循 Don't Repeat Yourself (DRY) 原則

按照慣例,ASP.NET 應用程序的默認布局文件命名為 _Layout.cshtml。Visual Studio ASP.NET Core MVC 項目模板包含這個布局文件,位置在 Views/Shared 文件夾:

這個布局為應用程序中的視圖定義了一個頂層模版。布局對應用程序來說不是必須的,應用程序也可以定義多個模板供不同的視圖使用。

一個 _Layout.cshtml 例子:

<!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 names="Development">
        <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
        <link rel="stylesheet" href="~/css/site.css" />
    </environment>
    <environment names="Staging,Production">
        <link rel="stylesheet" href="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.6/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>
    <div 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-area="" asp-controller="Home" asp-action="Index" class="navbar-brand">WebApplication1</a>
            </div>
            <div class="navbar-collapse collapse">
                <ul class="nav navbar-nav">
                    <li><a asp-area="" asp-controller="Home" asp-action="Index">Home</a></li>
                    <li><a asp-area="" asp-controller="Home" asp-action="About">About</a></li>
                    <li><a asp-area="" asp-controller="Home" asp-action="Contact">Contact</a></li>
                </ul>
                @await Html.PartialAsync("_LoginPartial")
            </div>
        </div>
    </div>
    <div class="container body-content">
        @RenderBody()
        <hr />
        <footer>
            <p>&copy; 2016 - WebApplication1</p>
        </footer>
    </div>

    <environment names="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 names="Staging,Production">
        <script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-2.2.0.min.js"
                asp-fallback-src="~/lib/jquery/dist/jquery.min.js"
                asp-fallback-test="window.jQuery">
        </script>
        <script src="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.6/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">
        </script>
        <script src="~/js/site.min.js" asp-append-version="true"></script>
    </environment>

    @RenderSection("scripts", required: false)
</body>
</html>

指定布局

Razor 視圖擁有一個 Layout 屬性。各個視圖可以通過設置這個屬性來指定布局:

@{
    Layout = "_Layout";
}

指定布局時可以用完整路徑(例如: /Views/Shared/_Layout.cshtml )或者部分名稱(例如: _Layout )。當使用部分名稱時,Razor 視圖引擎將使用它的標准發現流程搜索布局文件。首先 Controller 相關的文件夾,其次是 Shared 文件夾。這個發現流程和部分視圖的是完全相同的。

默認情況下,每個布局視圖必須調用 RenderBody 方法。在哪里調用 RenderBody ,視圖內容就會在那里被渲染。

Sections

布局視圖可以通過調用 RenderSection 方法來引用一個或多個 sections (布局視圖不是必須引用 Section)。Section 提供了組織某些頁面元素放置的方法。每一個 RenderSection 調用都可以指定 Secton 是必須還是可選的。如果找不到一個必須的 Section,會拋出異常。個別視圖使用 @section 指定被渲染的內容。如果一個視圖定義了一個 Section,它必須被渲染(否則將會發生錯誤)。(譯者注:這里的必須被渲染指必須通過 RenderSection 方法調用。)

一個在視圖中定義 @section 的例子:

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

在上面的代碼中,將驗證腳本添加到一個包含 Form 表單的視圖中的 scripts Section 中。其它在同一個應用程序的視圖也許不需要任何額外的腳本,所以不需要定義 scripts Section。

定義在視圖中的 Section 只在其相關的布局頁中可用。它們不能在局部視圖、視圖組件或視圖系統的其他部分中引用。(譯者注:Section 可以在任何視圖系統中定義,但只能在布局視圖中調用 RenderSection 進行渲染。)

忽略 Section

默認情況下,內容頁中 Body 和所有 Section 都必須在布局頁中渲染。Razor 視圖引擎通過跟蹤 Body 和每個 Section 是否被渲染來強制執行。

如果需要指示視圖引擎忽略 Body 和 Section,調用 IgnoreBodyIgnoreSection 方法。

在 Razor 頁面的 Body 和每個 Section 必須被渲染或忽略。

導入共享指令

視圖可以使用 Razor 指令做許多事,比如導入命名空間或者進行依賴注入。由多個視圖共享的指令可以在公共的 _ViewImports.cshtml 文件中指定。 _ViewImports 文件支持以下指令:

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

這個文件不支持其他 Razor 特性,比如 functions 和 section 的定義等等。

一個 _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 通常被放置在 Views 文件夾下。_ViewImports.cshtml 文件也可以放在任何文件夾下面,在這種情況下,它將只作用於該文件夾和其子文件夾下的視圖。在執行順序上,首先執行在根目錄下的 _ViewImports 文件,然后執行視圖所在文件夾下的 _ViewImports文件,所以在根目錄中 _ViewImports 文件里指定的設定可能會被覆蓋掉。

舉個例子,如果根目錄中 _ViewImports.cshtml 文件指定了 @model@addTagHelper,另外一個 Controller 相關文件夾下的 _ViewImports.cshtml 文件指定一個不同的 @model 並添加另外一個 @addTagHelper ,視圖將可訪問兩種 TagHelper 並使用后者指定的 @model

如果一個視圖中有多個 _ViewImports.cshtml 文件被運行,多個 ViewImports.cshtml 文件中指令的組合行為如下:

  • @addTagHelper, @removeTagHelper:按照順序全部運行
  • @tagHelperPrefix:離視圖最近的一個覆蓋其他的
  • @model:離視圖最近的一個覆蓋其他的
  • @inherits:離視圖最近的一個覆蓋其他的
  • @using:全部包含; 重復的忽略
  • @inject:對每一個屬性而言(通過屬性名區分),離視圖最近的一個覆蓋其他的

在視圖之前運行代碼

如果你有代碼需要在每個視圖之前運行,這些代碼應該放在 _ViewStart.cshtml 文件中。按照約定, _ViewStart.cshtml 文件位於 Views 文件夾。 _ViewStart.cshtml 中列出的語句會在所有完整的視圖(不包含布局視圖和部分視圖)之前運行。就像 ViewImports.cshtml_ViewStart.cshtml 也有優先級。如果一個 _ViewStart.cshtml 文件定義在 Controller 相關的視圖文件夾內,它將比 Views 文件夾根目錄下的 _ViewStart.cshtml 文件更晚運行(如果根目錄下有這個文件的話)。

一個 _ViewStart.cshtml 文件例子:

@{
    Layout = "_Layout";
}

上面的文件指定了所有的視圖將使用 _Layout.cshtml 布局視圖。

注意
通常無論 _ViewStart.cshtml 還是 _ViewImports.cshtml 都不能放在 /Views/Shared 文件夾下。應用程序級別的這些文件,應該直接放在 /Views 文件夾下。

返回目錄


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM