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 的前端設計工具可以編輯 Razor ,而不需學習 C# Razor 語法。

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

這與 HTML 協助程式相反,這是在檢視中 Razor 建立標記的先前方法。 標籤協助程式與 HTML 協助程式的比較會詳述差異。 標籤協助程式的 IntelliSense 支援說明 IntelliSense 環境。 即使是使用 C# 語法的 Razor 開發人員,使用標籤協助程式比撰寫 C# Razor 標記更具生產力。

讓您更具生產力且能夠使用伺服器上可用的資訊來產生更健全、可靠且可維護的程式碼的方法

例如,在更新映射時,在過去,更新映射的指令是變更映射的名稱。 基於效能考量,應該主動快取影像,而且除非您變更影像的名稱,否則用戶端會有取得過時複本的風險。 在過去,編輯映像之後,必須變更名稱,而且需要更新 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 資料夾和子資料夾中的所有檔案繼承;讓標籤協助程式可供使用。 上述程式碼會使用萬用字元語法 (「*」) 來指定指定元件中的所有標籤協助程式, (Microsoft.AspNetCore.Mvc.TagHelpers) 可供 Views 目錄或子目錄中的每個檢視檔案使用。 之後 @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

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

@removeTagHelper 會移除標籤協助程式

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

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

您可以將 加入 _ViewImports.cshtml 至任何檢視資料夾,而檢視引擎會從該檔案和 Views/_ViewImports.cshtml 檔案套用 指示詞。 如果您為檢視新增了空 Views/Home/_ViewImports.cshtmlHome 檔案,則不會有任何變更,因為檔案 _ViewImports.cshtml 是加總的。 @addTagHelper您新增至 Views/Home/_ViewImports.cshtml 檔案的任何指示詞 (不在預設 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 移除 屬性。

標籤協助程式初始化運算式

雖然屬性可用來設定標籤協助程式的個別實例, ITagHelperInitializer<TTagHelper> 但可用來設定特定種類的所有標籤協助程式實例。 請考慮下列標籤協助程式初始化運算式範例,以 asp-append-version 設定應用程式中所有 實例 ScriptTagHelper 的屬性或 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"})

(@) 符號的 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 網頁伺服器控制項會在頁面上宣告和叫用。

  • ASP.NET Web 服務器控制項有一個非簡單的生命週期,可讓開發和偵錯變得困難。

  • 網頁伺服器控制項可讓您使用用戶端控制項,來新增用戶端文件物件模型 (DOM) 項目的功能。 標籤協助程式沒有 DOM。

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

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

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

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

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

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

您可以從[工具>選項>] 環境>字型和色彩自訂字型和色彩的字型和色彩

Options dialog in Visual Studio

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

錨點標記協助程式

快取標籤協助程式

元件標籤協助程式

分散式快取標籤協助程式

環境標記協助程式

表單標記協助程式

表單動作標記協助程式

影像標記協助程式

輸入標記協助程式

標籤標記協助程式

連結標籤協助程式

Partial 標籤協助程式

腳本標籤協助程式

選取標籤協助程式

Textarea 標籤協助程式

驗證訊息標記協助程式

驗證摘要標記協助程式

其他資源