共用方式為


ASP.NET 核心中的標籤助手

作者:Rick Anderson

什麼是標籤助手

標籤輔助工具讓伺服器端程式碼能參與建立及渲染檔案中的 Razor HTML 元素。 例如,內建 ImageTagHelper 功能可以在圖片名稱後加上版本號。 每當映像檔變更時,伺服器會為該影像產生一個新的獨特版本,因此客戶端能保證取得目前的影像(而非過時的快取影像)。 內建許多標籤輔助工具可用於常見任務——例如建立表單、連結、載入資產等——而且更多則可在公開的 GitHub 倉庫和 NuGet 套件中提供。 標籤輔助工具是以 C# 撰寫,並根據元素名稱、屬性名稱或父標籤來鎖定 HTML 元素。 例如,當屬性被套用時,內建LabelTagHelper可鎖定 HTML <label> 元素中的LabelTagHelper。 如果你熟悉 HTML 助手,標籤輔助工具能減少檢視中 HTML 與 C# Razor 之間的明確過渡。 在許多情況下,HTML 助手提供了特定標籤助手的替代方式,但重要的是要認識到標籤助手並不能取代 HTML 助手,也沒有每個 HTML 助手都有標籤輔助工具。 標籤助手與 HTML 助手的比較更詳細說明了兩者的差異。

在Razor元件中,不支援標籤輔助器。 如需詳細資訊,請參閱 ASP.NET Core Razor 元件

標籤助手提供的功能

一個對 HTML 友善的開發體驗

大多數情況下, Razor 使用 Tag Helpers 的標記看起來就像標準 HTML。 熟悉 HTML/CSS/JavaScript 的前端設計師可以在不學 C# Razor 語法的情況下編輯Razor。

豐富的 IntelliSense 環境用於建立 HTML 與 Razor 標記

這與先前使用 HTML Helpers 在檢視中進行伺服器端標記建立的方法形成鮮明對比。 標籤助手與 HTML 助手的比較更詳細說明了兩者的差異。 IntelliSense 對標籤助手的支援 說明了 IntelliSense 的環境。 即使是熟悉 Razor C# 語法的開發者,使用標籤輔助工具也比撰寫 C# Razor 標記更有效率。

一種讓你更有效率,並能用伺服器上僅有資訊產出更健全、可靠且易於維護的程式碼的方法

舉例來說,歷史上更新圖片的口號是,只要更改圖片,就要同時更改圖片名稱。 為了提升效能,圖片應該被積極地進行快取,除非你更改圖片名稱,否則客戶可能會收到過期的副本。 歷史上,圖片編輯後必須更改名稱,且網頁應用程式中對圖片的每個參考資料都需更新。 這不僅非常費工,也容易出錯(你可能會錯過參考資料、錯誤輸入字串等等)。內建 ImageTagHelper 功能可以自動幫你做到這點。 他們 ImageTagHelper 可以在映像檔名稱後加上版本號,因此每當映像檔變更時,伺服器會自動產生一個新的、唯一版本。 客戶可以保證能看到目前的映像檔。 這種穩健性和節省人力的優勢基本上是天然來自於使用ImageTagHelper

大多數內建的標籤輔助工具針對標準 HTML 元素,並提供該元素的伺服器端屬性。 例如,在 <input> 資料夾中的許多檢視元素中使用 ,並包含屬性 asp-for。 此屬性會將指定模型屬性的名稱擷取到渲染後的 HTML 中。 考慮具有以下模型的Razor視圖:

public class Movie
{
    public int ID { get; set; }
    public string Title { get; set; }
    public DateTime ReleaseDate { get; set; }
    public string Genre { get; set; }
    public decimal Price { get; set; }
}

以下 Razor 標記:

<label asp-for="Movie.Title"></label>

產生下列 HTML:

<label for="Movie_Title">Title</label>

asp-for中,屬性For提供了LabelTagHelper屬性。 更多資訊請參閱 作者標籤助手

管理標籤輔助範圍

標籤助手的作用範圍是由 @addTagHelper@removeTagHelper 和「!」退出字元的組合來控制的。

@addTagHelper 讓標籤助手可用

如果您建立一個名為 AuthoringTagHelpers 的新 ASP.NET Core 網頁應用程式, Views/_ViewImports.cshtml 以下檔案將被加入您的專案中:

@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@addTagHelper *, AuthoringTagHelpers

指令允許 @addTagHelper 標籤輔助器(Tag Helpers)對視圖開放。 在這種情況下,檢視檔為 Pages/_ViewImports.cshtml,其預設會被 Pages 資料夾及子資料夾中的所有檔案繼承,使標籤輔助工具可用。 上述程式碼使用通配字語法(「*」)來指定指定組合(Microsoft.AspNetCore.Mvc.TagHelpers)中的所有標籤輔助器,將對 Views 目錄或子目錄中的每個檢視檔案開放。 接下來 @addTagHelper 的第一個參數指定要載入的標籤輔助器(我們使用「*」表示所有標籤輔助器),第二個參數「Microsoft.AspNetCore.Mvc.TagHelpers」則指定包含標籤輔助器的組合語言。 Microsoft.AspNetCore.Mvc.TagHelpers 是內建 ASP.NET 核心標籤輔助器的組件。

要公開本專案中所有的標籤輔助器(該專案會建立一個名為 AuthoringTagHelpers 的組合),你會使用以下工具:

@using AuthoringTagHelpers
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@addTagHelper *, AuthoringTagHelpers

如果您的專案包含 EmailTagHelper 預設命名空間(AuthoringTagHelpers.TagHelpers.EmailTagHelper),您可以提供標籤助手的完整限定名稱(FQN):

@using AuthoringTagHelpers
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@addTagHelper AuthoringTagHelpers.TagHelpers.EmailTagHelper, AuthoringTagHelpers

要在使用 FQN 的檢視中新增標籤輔助器,首先加入 FQN (AuthoringTagHelpers.TagHelpers.EmailTagHelper),接著加入組合名稱(AuthoringTagHelpers)。 大多數開發者偏好使用「*」萬用字元語法。 萬用字元語法允許你在 FQN 中插入萬用字元「*」作為後綴。 例如,以下任一指令都會引入EmailTagHelper

@addTagHelper AuthoringTagHelpers.TagHelpers.E*, AuthoringTagHelpers
@addTagHelper AuthoringTagHelpers.TagHelpers.Email*, AuthoringTagHelpers

如前所述,將指令加入@addTagHelperViews/_ViewImports.cshtml檔案後,標籤輔助器可對 Views 目錄及子目錄中的所有檢視檔案使用。 如果你想選擇只讓標籤助手只對這些檢視開放,可以在特定的檢視檔案中使用這個 @addTagHelper 指令。

@removeTagHelper 移除標籤協助器

@removeTagHelper@addTagHelper 具有相同的兩個參數,並且會移除先前新增的標籤輔助器。 例如, @removeTagHelper 套用到特定視圖會移除指定的標籤輔助器。 在檔案中使用@removeTagHelperViews/Folder/_ViewImports.cshtml會移除資料夾中所有視圖中指定的標籤輔助工具。

_ViewImports.cshtml 檔案控制標籤輔助範圍

你可以將 _ViewImports.cshtml 加入任何檢視資料夾,檢視引擎會套用該檔案和 Views/_ViewImports.cshtml 檔案的指令。 如果你為 Views/Home/_ViewImports.cshtml 視圖新增了一個空 Home 檔案,因為該 _ViewImports.cshtml 檔案具有累加性,所以不會有任何變化。 @addTagHelper加到Views/Home/_ViewImports.cshtml檔案的任何指令(不在預設Views/_ViewImports.cshtml檔案中),會使這些標籤輔助工具僅在Home資料夾中的視圖中可用。

選擇不使用單一元素

你可以在元素層級用標籤輔助者退出角色(「!」)來停用標籤助手。 例如, Email 驗證功能在標籤助手退出字元中被禁用 <span>

<!span asp-validation-for="Email" class="text-danger"></!span>

您必須將標籤輔助程式退出字元套用到起始和結束標籤上。 (當你在開場標籤新增退出字元時,Visual Studio 編輯器會自動將退出字元加入關閉標籤。) 加入退出字元後,元素和標籤助手屬性將不再以獨特字體顯示。

@tagHelperPrefix 來明確表示標籤輔助器的使用方式

@tagHelperPrefix 指令允許你指定標籤前綴字串,以啟用 Tag Helper 支援並明確使用標籤輔助器。 例如,你可以在檔案中新增以下標記 Views/_ViewImports.cshtml

@tagHelperPrefix th:

在下方的程式碼映像中,Tag Helper 前綴設為 th:,因此只有使用該前綴 th: 的元素才支援 Tag Helpers(啟用 Tag Helper 的元素有獨特字型)。 <label><input> 元素帶有標籤參考前綴且已啟用標籤參考,而 <span> 元素則沒有。

Razor 使用 Tag Helper 前綴設為「th:」以標記標籤及輸入元素名稱

同樣 @addTagHelper 適用於 的階層規則也適用於 @tagHelperPrefix

自動關閉標籤輔助器

許多標籤輔助器無法作為自動關閉標籤使用。 有些標籤輔助器設計成自動關閉標籤。 使用非設計為自動關閉的標籤輔助工具會抑制渲染輸出。 標籤協助器的自我關閉會在渲染輸出中產生自我關閉標籤。 更多資訊請參閱「撰寫標籤助手」中的說明

C# 在 Tag Helpers 屬性/宣告中

標籤輔助工具不允許在元素的屬性或標籤宣告區使用 C#。 例如,以下程式碼不適用:

<input asp-for="LastName"  
       @(Model?.LicenseId == null ? "disabled" : string.Empty) />

前述程式碼可寫為:

<input asp-for="LastName" 
       disabled="@(Model?.LicenseId == null)" />

通常,運算子 @ 會在渲染後的 HTML 標記中插入表達式的文字表示。 然而,當表達式被評估為邏輯值 false 時,框架會移除該屬性。 在前述範例中,若 disabledtrueModel,則 LicenseId 屬性設為 null

標籤輔助初始化器

屬性可用於配置標籤輔助器的個別實例,但 ITagHelperInitializer<TTagHelper> 也可用於配置所有特定類型的標籤輔助實例。 請考慮以下標籤輔助器初始化器的範例,該程式會為應用程式中所有asp-append-version實例設定AppendVersion屬性或ScriptTagHelper屬性:

public class AppendVersionTagHelperInitializer : ITagHelperInitializer<ScriptTagHelper>
{
    public void Initialize(ScriptTagHelper helper, ViewContext context)
    {
        helper.AppendVersion = true;
    }
}

要使用初始化工具,請在應用程式啟動時將其註冊為一部分來設定:

builder.Services.AddSingleton
    <ITagHelperInitializer<ScriptTagHelper>, AppendVersionTagHelperInitializer>();

Tag Helper 自動生成位於 wwwroot 之外的版本

如需標籤協助程式為外部 wwwroot靜態檔案產生版本,請參閱 從多個位置提供檔案

IntelliSense 對標籤輔助器的支援

考慮寫一個 HTML <label> 元素。 一進入 <l Visual Studio 編輯器,IntelliSense 就會顯示相符的元素:

在鍵盤上輸入「l」後,IntelliSense 會建議列出可能的標籤名稱,並選擇「label」。

你不僅能獲得 HTML 的幫助,還有圖示(下方有「<>」的「@」符號)。

「@」符號下方有「<>」的符號。

圖示標示標籤助手鎖定的元素。 純 HTML 元素(例如 fieldset)會顯示「<>」圖示。

純 HTML <label> 標籤會以棕色字體顯示 HTML 標籤(預設的 Visual Studio 色彩主題),屬性以紅色顯示,屬性值以藍色顯示。

範例「標籤」HTML 標籤

輸入 <label後,IntelliSense 會列出可用的 HTML/CSS 屬性及標籤助手目標屬性:

使用者輸入了開頭括號和 HTML 元素名稱「label」。IntelliSense 會列出可能的屬性(沒有預設屬性)。

IntelliSense 的陳述式補全允許你輸入 tab 鍵,以選定的值完成陳述句:

使用者輸入開頭括號、HTML 元素名稱「label」,並開始輸入屬性名稱(「as」)。IntelliSense 會呈現一個選項對話框,選取「asp-for」。

一旦輸入標籤輔助屬性,標籤與屬性字型就會改變。 使用預設的 Visual Studio 「藍色」或「淺色」主題,字體為粗體紫色。 如果你用的是「深色」主題,字體是粗青綠色。 本文件中的圖片是使用預設主題拍攝的。

使用者選擇了「asp-for」,現在以粗體紫色標示,因為使用者沒有使用暗色主題。

你可以在雙引號("")內輸入 Visual Studio 的 CompleteWord 快捷鍵(預設為 Ctrl + 空白鍵),這樣你就會進入 C# 語境,就像在 C# 類別裡一樣。 IntelliSense 會顯示所有方法與屬性在頁面模型上。 這些方法和屬性之所以可用,是因為屬性類型為 ModelExpression。 在下方圖片中,我正在編輯 Register 視圖,所以 RegisterViewModel 是可用的。

使用者在「asp-for」屬性的值中輸入「e」。IntelliSense 建議選擇「電子郵件」即可完成。

IntelliSense 在頁面上列出模型可用的屬性與方法。 豐富的 IntelliSense 環境幫助你選擇 CSS 類別:

使用者輸入「cl」以在「輸入」元素中加入屬性。IntelliSense 會呈現一份選擇「類別」的完成建議清單。

使用者輸入「co」作為「輸入」元素的「class」屬性值。IntelliSense 提供一份選擇「col」的完成建議清單。

標籤輔助工具與 HTML 輔助工具的比較

標籤輔助器會附加在 Razor 視圖中的 HTML 元素上,而 HTML 輔助器則以方法的形式穿插於 Razor 視圖中的 HTML。 請考慮以下 Razor 標記,它建立一個帶有 CSS 類別「caption」的 HTML 標籤:

@Html.Label("FirstName", "First Name:", new {@class="caption"})

at(@) 符號表示 Razor 這是程式碼的起始。 接下來的兩個參數(「FirstName」和「First Name:」)是字串,所以 IntelliSense 無法幫忙。 最後的論點:

new {@class="caption"}

是一個用於表示屬性的匿名物件。 因為 class 是 C# 中的保留關鍵字,你用符號 @ 強制 C# 將其解讀 @class= 為符號(屬性名稱)。 對前端設計師(熟悉 HTML/CSS/JavaScript 及其他客戶端技術,但不熟悉 C# 和 Razor)來說,大部分領域都很陌生。 整條線必須在無 IntelliSense 幫助下撰寫。

利用 LabelTagHelper,相同的標記可寫成:

<label class="caption" asp-for="FirstName"></label>

在 Tag Helper 版本中,只要你進入 <l Visual Studio 編輯器,IntelliSense 就會顯示相符的元素:

使用者在鍵盤上輸入「l」。IntelliSense 建議在選擇「label」後完成 HTML 元素。

IntelliSense 幫你寫完整句話。

以下程式碼圖片展示了從 Visual Studio 附帶的 ASP.NET 4.5.x MVC 範本產生的部分表單視圖 Views/Account/Register.cshtmlRazor 。

Razor ASP.NET 4.5 MVC 專案範本中「註冊 Razor」檢視的表單部分標記

Visual Studio 編輯器會顯示灰色背景的 C# 程式碼。 例如, AntiForgeryToken HTML 助手:

@Html.AntiForgeryToken()

以灰色背景展示。 登錄器檢視中的大部分標記是 C#。 將這點與使用 Tag Helpers(標籤助手)的等效方法進行比較:

Razor 在 ASP.NET Core 專案範本的註冊 Razor 檢視表單部分,使用 Tag Helpers 進行標記

這種標記比 HTML Helpers 方法更乾淨、更易閱讀、編輯和維護。 C# 程式碼被簡化到伺服器需要知道的最低限度。 Visual Studio 編輯器會以獨特字體顯示由標籤輔助工具鎖定的標記。

電子郵件 群組為例:

<div class="form-group">
    <label asp-for="Email" class="col-md-2 control-label"></label>
    <div class="col-md-10">
        <input asp-for="Email" class="form-control" />
        <span asp-validation-for="Email" class="text-danger"></span>
    </div>
</div>

每個「asp-」屬性都有一個值「Email」,但「Email」不是字串。 在此語境中,「Email」是 C# 模型表達式的 RegisterViewModel 屬性。

Visual Studio 編輯器協助你在註冊表單的 Tag Helper 方法中撰寫 所有 標記,而對於 HTML Helpers 方法中的大部分程式碼,Visual Studio 並沒有提供協助。 IntelliSense 對標籤輔助器的支援 ,詳細說明了在 Visual Studio 編輯器中如何操作標籤輔助器。

標籤輔助工具與網頁伺服器控制的比較

  • 標籤助手並不擁有其所關聯的元素;他們僅協助元素及內容的呈現。 ASP.NET 網頁伺服器控制在頁面上宣告並呼叫。

  • ASP.NET 網頁伺服器控制項具有非簡單的生命週期,可能使開發與除錯變得困難。

  • 網頁伺服器控制項允許你透過客戶端控制項為客戶端的 DOM 元素添加功能。 Tag Helpers 並不包含 DOM。

  • 網頁伺服器控制包括自動瀏覽器偵測功能。 標籤助理對瀏覽器一無所知。

  • 多個標籤輔助器可以對同一元素採取行動(參見 避免標籤輔助器衝突),而通常無法組合網頁伺服器控制項。

  • 標籤助理可以修改他們所涵蓋的 HTML 元素的標籤和內容,但不會直接修改頁面上的其他內容。 網頁伺服器控制項的範圍較不具體,且可能執行影響頁面其他部分的動作;導致意外副作用。

  • 網頁伺服器控制項使用型別轉換器將字串轉換成物件。 使用 Tag Helpers 時,你可以原生使用 C#,所以不需要做型別轉換。

  • 網頁伺服器控制項用於 System.ComponentModel 實作元件與控制項的執行時與設計時行為。 System.ComponentModel 包含實作屬性與型別轉換器、綁定資料來源及授權元件的基底類別與介面。 與此相比,Tag Helpers 通常源自TagHelper,而TagHelper基底類別只暴露兩個方法,ProcessProcessAsync

自訂 Tag Helper 元素字型

你可以從 工具>選項>環境>字體與顏色中自訂字型與色彩:

Visual Studio 中的選項對話框

內建 ASP.NET 核心標籤輔助器

快取

元件

分散式快取

環境

表格

表單動作

影像

輸入

標籤

鏈結

部分

持久化元件狀態

劇本

選取

文字區

驗證訊息

驗證摘要

其他資源