ASP.NET Core 中的標記協助程式

作者:Rick Anderson

什麼是標籤協助程式

標籤協助程式可啟用伺服器端程式碼,以參與建立和轉譯 Razor 檔案中的 HTML 元素。 例如,內建 ImageTagHelper 可以將版本號碼附加至映像名稱。 只要映像變更,伺服器就會產生映像的新唯一版本,以保證用戶端可以取得最新的映像 (而不是過期的快取映像)。 有許多適用於一般工作 (例如建立表單和連結、載入資產等) 的內建標籤協助程式,還有更多位於公用 GitHub 存放庫及作為 NuGet 套件來提供。 標籤協助程式是以 C# 撰寫,並根據元素名稱、屬性名稱或上層標籤來設定目標 HTML 元素。 例如,套用 LabelTagHelper 屬性時,內建 LabelTagHelper 可以將目標設為 HTML <label> 項目。 如果您熟悉 HTML 協助程式,標籤協助程式可減少檢視中 Razor HTML 與 C# 之間的明確轉換。 在許多情況下,HTML 協助程式都會提供特定標籤協助程式的替代方式,但請務必辨識標籤協助程式未取代 HTML 協助程式,而且每個 HTML 協助程式都沒有標籤協助程式。 標籤協助程式與 HTML 協助程式的比較會詳述差異。

Razor 元件不支援標籤協助程式。 如需詳細資訊,請參閱 ASP.NET Core Razor 元件

標籤協助程式所提供的內容

HTML 友善的開發體驗

在大部分情況下,使用標籤協助程式的 Razor 標記看起來就像標準 HTML。 熟悉 HTML/CSS/JavaScript 的前端設計人員不需要學習 C# Razor 語法,就可以編輯 Razor。

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

這與 HTML 協助程式形成鮮明對比,這是伺服器端先前在 Razor 檢視中建立標記的方法。 標籤協助程式與 HTML 協助程式的比較會詳述差異。 標籤協助程式的 IntelliSense 支援說明 IntelliSense 環境。 有 Razor C# 語法使用經驗的開發人員,使用標籤 (tag) 協助程式會比使用撰寫 C# Razor 標記 (markup) 更具生產力。

這種方法讓您更具生產力且能夠使用僅只伺服器上可用的資訊,產生更強固、可靠且可維護的程式碼

例如,歷史上更新映像的口頭禪就是在變更映像時變更映像的名稱。 基於效能考量,應該主動快取影像,而且除非您變更影像的名稱,否則用戶端會有取得過時複本的風險。 在過去,編輯映像之後,必須變更名稱,而且需要更新 Web 應用程式中映像的每個參考。 這不只十分耗人力,也很容易發生錯誤 (您可能遺漏參考、不小心地輸入錯誤字串,依此類推)內建 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>

LabelTagHelper 中的 For屬性 (property) 可以使用 asp-for 屬性 (attribute)。 如需詳細資訊,請參閱編寫標籤協助程式

管理標籤協助程式範圍

標籤協助程式範圍是透過 @addTagHelper@removeTagHelper 和 "!" 退出字元的組合所控制。

@addTagHelper 讓標籤協助程式可用

如果您建立名為 AuthoringTagHelpers 的新 ASP.NET Core Web 應用程式,則會將下列 Views/_ViewImports.cshtml 檔案新增至您的專案:

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

@addTagHelper 指示詞讓標籤協助程式可供檢視使用。 在此情況下,檢視檔案是 Pages/_ViewImports.cshtml,預設會由 Pages 資料夾和子資料夾中的所有檔案繼承;讓標籤協助程式可用。 上述程式碼使用萬用字元語法 ("*"),指定 Views 目錄或子目錄中每個檢視檔案皆可使用指定組件 (Microsoft.AspNetCore.Mvc.TagHelpers) 中的所有標籤協助程式。 @addTagHelper 後面的第一個參數指定要載入的標籤協助程式 (使用 "*" 表示所有標籤協助程式),而第二個參數 "Microsoft.AspNetCore.Mvc.TagHelpers" 指定包含標籤協助程式的組件。 Microsoft.AspNetCore.Mvc.TagHelpers 是內建 ASP.NET Core 標籤協助程式的組件。

若要公開此專案中的所有標籤協助程式 (這會建立名為 AuthoringTagHelpers 的組件),請使用下列內容:

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

如果您的專案包含具有預設命名空間 (AuthoringTagHelpers.TagHelpers.EmailTagHelper) 的 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

如前所述,將 @addTagHelper 指示詞新增至 Views/_ViewImports.cshtml 檔案,讓 Views 目錄和子目錄中的所有檢視檔案都能使用標籤協助程式。 如果您想要選擇只向那些檢視公開標籤協助程式,則可以使用特定檢視檔案中的 @addTagHelper 指示詞。

@removeTagHelper 會移除標籤協助程式

@removeTagHelper 有兩個參數與 @addTagHelper 相同,而且會移除先前新增的標籤協助程式。 例如,套用至特定檢視的 @removeTagHelper 會從檢視中移除指定的標籤協助程式。 在 Views/Folder/_ViewImports.cshtml 檔案中使用 @removeTagHelper,會從 Folder 的所有檢視中移除所指定的標籤協助程式。

使用 _ViewImports.cshtml 檔案控制標籤協助程式範圍

您可以將 _ViewImports.cshtml 新增至任何檢視資料夾,而且檢視引擎會套用該檔案和 Views/_ViewImports.cshtml 檔案中的指示詞。 如果您為 Home 檢視新增了空白的 Views/Home/_ViewImports.cshtml 檔案,則不會有任何變更,因為 _ViewImports.cshtml 檔案是附加的。 您新增至 Views/Home/_ViewImports.cshtml 檔案的任何 @addTagHelper 指示詞 (不在預設 Views/_ViewImports.cshtml 檔案中),只會將這些標籤協助程式公開至 Home 資料夾中的檢視。

退出個別項目

您可以停用項目層級中包含標籤協助程式退出字元 ("!") 的標籤協助程式。 例如,在包含標籤協助程式退出字元的 <span> 中,停用 Email 驗證:

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

您必須將標籤協助程式退出字元套用至開頭和結尾標籤 (將退出字元新增至開頭標籤時,Visual Studio 編輯器會將退出字元自動新增至結尾標籤)。 在您新增退出字元之後,就不會再以特殊字型顯示項目和標籤協助程式屬性。

使用 @tagHelperPrefix 以明確使用標籤協助程式

@tagHelperPrefix 指示詞可讓您指定標籤前置詞字串以啟用標籤協助程式支援,並明確使用。 例如,您可以將下列標記新增至 Views/_ViewImports.cshtml 檔案:

@tagHelperPrefix th:

在下列程式碼影像中,標籤協助程式前置詞設定為 th:,因此只有使用前置詞 th: 的項目才支援標籤協助程式 (啟用標籤協助程式的項目具有特殊字型)。 <label><input> 項目具有標籤協助程式前置詞並且已啟用標籤協助程式,而 <span> 項目則否。

Razor markup with Tag Helper prefix set to

套用至 @addTagHelper 的相同階層規則也會套用至 @tagHelperPrefix

自行結尾的標籤協助程式

許多標籤協助程式無法作為自行結尾的標籤。 某些標籤協助程式專門用作自行結尾的標籤。 使用非專門用作自行結尾的標籤協助程式會隱藏轉譯輸出。 讓標籤協助程式自行結尾,會在轉譯輸出中產生自行結尾的標籤。 如需詳細資訊,請參閱編寫標籤協助程式中的這項附註

標籤協助程式屬性/宣告中的 C#

標籤協助程式不允許在元素的屬性或標籤宣告區域中使用 C#。 例如,下列程式碼無效:

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

上述程式碼可撰寫為:

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

一般而言,@ 運算子會將運算式的文字表示法插入已轉譯的 HTML 標記中。 不過,當運算式評估為邏輯 false 時,架構會改為移除此屬性。 在上述範例中,如果 ModelLicenseIdnull,則 disabled 屬性會設定為 true

標籤協助程式初始設定式

雖然屬性可用於設定標籤協助程式的個別執行個體,但 ITagHelperInitializer<TTagHelper> 可用於設定特定種類的所有標籤協助程式執行個體。 請考慮標籤協助程式初始設定式的下列範例,該初始設定式會針對應用程式中的所有 ScriptTagHelper 執行個體設定 asp-append-version 屬性或 AppendVersion 屬性:

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

若要使用初始設定式,請將其註冊為應用程式啟動的一部分來進行設定:

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

在 wwwroot 外部的標籤協助程式自動版本產生

若要讓標籤協助程式在 wwwroot 外部產生靜態檔案的版本,請參閱從多個位置提供檔案

標籤協助程式的 IntelliSense 支援

請考慮撰寫 HTML <label> 項目。 只要您在 Visual Studio 編輯器中輸入 <l,IntelliSense 就會顯示相符的項目:

After typing

您不僅會取得 HTML 說明,還會取得圖示 (其底下有 "<>" 的 "@" 符號)。

The

此圖示可識別標籤協助程式設為目標的元素。 純 HTML 元素 (例如 fieldset) 會顯示 "<>" 圖示。

純 HTML <label> 標籤會以棕色字型顯示 HTML 標籤 (具有預設 Visual Studio 色彩佈景主題)、以紅色顯示屬性,並以藍色顯示屬性值。

Example

在您輸入 <label 之後,IntelliSense 會列出可用的 HTML/CSS 屬性以及設為目標的標籤協助程式屬性:

The user has typed an opening bracket and the HTML element name

IntelliSense 陳述式完成可讓您輸入 Tab 鍵,來完成具有所選取值的陳述式:

The user has typed an opening bracket, the HTML element name

只要輸入標籤協助程式屬性,標籤和屬性字型就會變更。 使用預設 Visual Studio "Blue" 或 "Light" 色彩佈景主題,而且字型為粗體紫色。 如果要使用 "Dark" 佈景主題,則字型是粗體藍綠色。 本文件中的影像是使用預設佈景主題所取得。

The user selected

您可以在雙引號 ("") 內輸入 Visual Studio CompleteWord 快速鍵 (Ctrl+空格鍵是預設值),而且現在可以使用 C#,就像使用 C# 類別一樣。 IntelliSense 會顯示頁面模型上的所有方法和屬性。 因為屬性類型是 ModelExpression,所以可以使用方法和屬性。 在下列影像中,我正在編輯 Register 檢視,因此 RegisterViewModel 可供使用。

The user types

IntelliSense 會列出頁面上模型可用的屬性和方法。 豐富的 IntelliSense 環境可協助您選取 CSS 類別:

The user types

The user types

標籤協助程式與 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>

使用標籤協助程式版本時,只要您在 Visual Studio 編輯器中輸入 <l,IntelliSense 就會顯示相符的項目:

The user types

IntelliSense 可協助您撰寫整行。

下列程式碼影像顯示從 Visual Studio 所含 ASP.NET 4.5.x MVC 範本產生之 Views/Account/Register.cshtmlRazor 檢視的「表單」部分。

Razor markup for the form portion of the Register Razor view for ASP.NET 4.5 MVC project template

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

@Html.AntiForgeryToken()

以灰色背景顯示。 註冊檢視中的大部分標記都是 C#。 將該方法與使用標籤協助程式的對等方法進行比較:

Razor markup with Tag Helpers for the form portion of the Register Razor view for an ASP.NET Core project template

與 HTML 協助程式方法相較之下,標記更為簡潔,而且更容易讀取、編輯和維護。 C# 程式碼會減少到伺服器所知道的最小值。 Visual Studio 編輯器會以特殊字型顯示標籤 (tag) 協助程式設為目標的標籤 (markup)。

請考慮使用 Email 群組:

<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" 是 RegisterViewModel 的 C# 模型運算式屬性。

Visual Studio 編輯器可協助您撰寫註冊表單之標籤 (tag) 協助程式方法中的所有標籤 (markup),而 Visual Studio 不提供 HTML 協助程式方法中大部分程式碼的協助。 標籤協助程式的 IntelliSense 支援會詳述如何在 Visual Studio 編輯器中使用標籤協助程式。

標籤協助程式與網頁伺服器控制項的比較

  • 標籤協助程式未擁有與其建立關聯的項目;它們只會參與轉譯項目和內容。 ASP.NET Web 伺服器控制項是在頁面上宣告和叫用。

  • ASP.NET 網頁伺服器控制項的非一般生命週期讓開發和偵錯更為困難。

  • 網頁伺服器控制項可讓您使用用戶端控制項,來新增用戶端 DOM 元素的功能。 標籤協助程式沒有 DOM。

  • Web 伺服器控制項包括自動瀏覽器偵測。 標籤協助程式不知道瀏覽器。

  • 雖然您通常無法撰寫網頁伺服器控制項,但是多個標籤協助程式可以處理相同的元素 (請參閱避免標籤協助程式衝突)。

  • 標籤協助程式可以修改設為其範圍之 HTML 項目的標籤和內容,但不會直接修改頁面上的其他任何項目。 網頁伺服器控制項的範圍更為廣泛,而且可以執行的動作會影響您網頁的其他部分;具有非預期的副作用。

  • 網頁伺服器控制項使用類型轉換器以將字串轉換成物件。 使用標籤協助程式時,您可以使用 C# 以原生方式工作,因此不需要進行類型轉換。

  • 網頁伺服器控制項使用 System.ComponentModel,實作元件和控制項的執行階段和設計階段行為。 System.ComponentModel 包含基底類別和介面,以便實作屬性和類型轉換器、繫結至資料來源,以及授權元件。 與一般衍生自 TagHelper 的標籤協助程式相反,而且 TagHelper 基底類別只會公開兩個方法:ProcessProcessAsync

自訂標籤協助程式項目字型

您可以從 [工具]>[選項]>[環境][字型和色彩]> 來自訂字型和顏色標示:

Options dialog in Visual Studio

內建的 ASP.NET Core 標記協助程式

錨點

Cache

元件

分散式快取

環境

表單

表單動作

映像

輸入

標籤

連結

Partial

保存元件狀態

指令碼

選取

文字區域

驗證訊息

驗證摘要

其他資源