ASP.NET Core 中的標籤協助程式元件
作者:Scott Addie 和 Fiyaz Bin Hasan
標籤協助程式元件是一種標籤協助程式,允許您從伺服器端程式碼有條件地修改或新增 HTML 項目。 ASP.NET Core 2.0 或更新版本提供此功能。
ASP.NET Core 包含兩個內建標籤協助程式元件:head
和 body
。 它們會位於 Microsoft.AspNetCore.Mvc.Razor.TagHelpers 命名空間中,可用於 MVC 和 Razor Pages。 標籤協助程式元件不需要在 _ViewImports.cshtml
中向應用程式註冊。
檢視或下載範例程式碼 \(英文\) (如何下載)
使用案例
兩個常見的標籤協助程式元件的使用案例為:
下列各節描述這些案例。
插入 HTML 標頭項目
在 HTML <head>
項目中,CSS 檔案一般與 HTML <link>
項目一起匯入。 下列程式碼會使用 head
標籤協助程式元件,將 <link>
項目插入 <head>
項目:
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Razor.TagHelpers;
namespace RazorPagesSample.TagHelpers
{
public class AddressStyleTagHelperComponent : TagHelperComponent
{
private readonly string _style =
@"<link rel=""stylesheet"" href=""/css/address.css"" />";
public override int Order => 1;
public override Task ProcessAsync(TagHelperContext context,
TagHelperOutput output)
{
if (string.Equals(context.TagName, "head",
StringComparison.OrdinalIgnoreCase))
{
output.PostContent.AppendHtml(_style);
}
return Task.CompletedTask;
}
}
}
在上述程式碼中:
AddressStyleTagHelperComponent
會實作 TagHelperComponent。 抽象:- 允許使用 TagHelperContext 初始化類別。
- 可讓您使用標籤協助程式元件新增或修改 HTML 項目。
- Order 屬性會定義元件的轉譯順序。 當應用程式中有多種標籤協助元件用法時,則
Order
為必要。 - ProcessAsync 會將執行內容的 TagName 屬性值與
head
進行比較。 如果比較評估為 True,則_style
欄位的內容會插入 HTML<head>
項目。
插入 HTML 本文項目
body
標籤協助程式元件可將 <script>
項目插入 <body>
項目。 下列程式碼示範這項技術:
using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Razor.TagHelpers;
namespace RazorPagesSample.TagHelpers
{
public class AddressScriptTagHelperComponent : TagHelperComponent
{
public override int Order => 2;
public override async Task ProcessAsync(TagHelperContext context,
TagHelperOutput output)
{
if (string.Equals(context.TagName, "body",
StringComparison.OrdinalIgnoreCase))
{
var script = await File.ReadAllTextAsync(
"TagHelpers/Templates/AddressToolTipScript.html");
output.PostContent.AppendHtml(script);
}
}
}
}
個別的 HTML 檔案用於儲存 <script>
項目。 該 HTML 檔案會使程式碼更簡潔且更容易維護。 上述程式碼會讀取 TagHelpers/Templates/AddressToolTipScript.html
的內容,並將它附加至標籤協助程式輸出。 AddressToolTipScript.html
檔案包含下列標記:
<script>
$("address[printable]").hover(function() {
$(this).attr({
"data-toggle": "tooltip",
"data-placement": "right",
"title": "Home of Microsoft!"
});
});
</script>
上述程式碼會將 啟動程序工具提示小工具繫結至包含 printable
屬性的任何 <address>
項目。 當滑鼠指標停留在項目上時,會顯示效果。
註冊元件
標籤協助程式元件必須新增至應用程式的標籤協助程式元件集合中。 有三種方式可新增至集合:
透過服務容器註冊
如果標籤協助程式元件類別並未以 ITagHelperComponentManager 管理,則必須使用相依性插入 (DI) 系統來註冊。 下列 Startup.ConfigureServices
程式碼會使用暫時性存留期來註冊 AddressStyleTagHelperComponent
與 AddressScriptTagHelperComponent
類別:
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddTransient<ITagHelperComponent,
AddressScriptTagHelperComponent>();
services.AddTransient<ITagHelperComponent,
AddressStyleTagHelperComponent>();
}
透過 Razor 檔案註冊
如果標籤協助程式元件未向 DI 註冊,則可以從 Razor Pages 頁面或 MVC 檢視進行註冊。 這項技術用於控制插入的標記和來自 Razor 檔案的元件執行順序。
ITagHelperComponentManager
用於新增標籤協助程式元件,或從應用程式移除。 下列程式碼使用 AddressTagHelperComponent
示範這項技術:
@using RazorPagesSample.TagHelpers;
@using Microsoft.AspNetCore.Mvc.Razor.TagHelpers;
@inject ITagHelperComponentManager manager;
@{
string markup;
if (Model.IsWeekend)
{
markup = "<em class='text-warning'>Office closed today!</em>";
}
else
{
markup = "<em class='text-info'>Office open today!</em>";
}
manager.Components.Add(new AddressTagHelperComponent(markup, 1));
}
在上述程式碼中:
@inject
指示詞會提供ITagHelperComponentManager
的執行個體。 該執行個體會指派給名為manager
的變數,以存取 Razor 檔案中的下游。AddressTagHelperComponent
的執行個體會新增至應用程式標籤協助程式元件集合。
AddressTagHelperComponent
已修改,以容納接受 markup
和 order
參數的建構函式:
private readonly string _markup;
public override int Order { get; }
public AddressTagHelperComponent(string markup = "", int order = 1)
{
_markup = markup;
Order = order;
}
提供的 markup
參數會用於 ProcessAsync
,如下所示:
public override async Task ProcessAsync(TagHelperContext context,
TagHelperOutput output)
{
if (string.Equals(context.TagName, "address",
StringComparison.OrdinalIgnoreCase) &&
output.Attributes.ContainsName("printable"))
{
TagHelperContent childContent = await output.GetChildContentAsync();
string content = childContent.GetContent();
output.Content.SetHtmlContent(
$"<div>{content}<br>{_markup}</div>{_printableButton}");
}
}
透過頁面模型或控制器註冊
如果標籤協助程式元件並未註冊為 DI,則可以從 Razor Pages 模型或 MVC 控制器進行註冊。 這項技術可用於將 C# 邏輯從 Razor 檔案分開。
建構函式插入可用於存取 ITagHelperComponentManager
的執行個體。 標籤協助程式元件會新增至執行個體的標籤協助程式元件集合。 下列 Razor 頁面的頁面模型使用 AddressTagHelperComponent
來示範這項技術:
using System;
using Microsoft.AspNetCore.Mvc.Razor.TagHelpers;
using Microsoft.AspNetCore.Mvc.RazorPages;
using RazorPagesSample.TagHelpers;
public class IndexModel : PageModel
{
private readonly ITagHelperComponentManager _tagHelperComponentManager;
public bool IsWeekend
{
get
{
var dayOfWeek = DateTime.Now.DayOfWeek;
return dayOfWeek == DayOfWeek.Saturday ||
dayOfWeek == DayOfWeek.Sunday;
}
}
public IndexModel(ITagHelperComponentManager tagHelperComponentManager)
{
_tagHelperComponentManager = tagHelperComponentManager;
}
public void OnGet()
{
string markup;
if (IsWeekend)
{
markup = "<em class='text-warning'>Office closed today!</em>";
}
else
{
markup = "<em class='text-info'>Office open today!</em>";
}
_tagHelperComponentManager.Components.Add(
new AddressTagHelperComponent(markup, 1));
}
}
在上述程式碼中:
- 建構函式插入可用於存取
ITagHelperComponentManager
的執行個體。 AddressTagHelperComponent
的執行個體會新增至應用程式標籤協助程式元件集合。
建立元件
建立自訂標籤協助程式元件:
- 建立衍生自 TagHelperComponentTagHelper 的公用類別。
- 將
[HtmlTargetElement]
屬性套用至該類別。 指定目標 HTML 項目的名稱。 - 選擇性:將
[EditorBrowsable(EditorBrowsableState.Never)]
屬性套用至該類別,以隱藏 IntelliSense 中的類型顯示。
下列程式碼會建立以 <address>
HTML 項目為目標的自訂標籤協助程式元件:
using System.ComponentModel;
using Microsoft.AspNetCore.Mvc.Razor.TagHelpers;
using Microsoft.AspNetCore.Razor.TagHelpers;
using Microsoft.Extensions.Logging;
namespace RazorPagesSample.TagHelpers
{
[HtmlTargetElement("address")]
[EditorBrowsable(EditorBrowsableState.Never)]
public class AddressTagHelperComponentTagHelper : TagHelperComponentTagHelper
{
public AddressTagHelperComponentTagHelper(
ITagHelperComponentManager componentManager,
ILoggerFactory loggerFactory) : base(componentManager, loggerFactory)
{
}
}
}
使用自訂 address
標籤協助程式元件來插入 HTML 標記,如下所示:
public class AddressTagHelperComponent : TagHelperComponent
{
private readonly string _printableButton =
"<button type='button' class='btn btn-info' onclick=\"window.open(" +
"'https://binged.it/2AXRRYw')\">" +
"<span class='glyphicon glyphicon-road' aria-hidden='true'></span>" +
"</button>";
public override int Order => 3;
public override async Task ProcessAsync(TagHelperContext context,
TagHelperOutput output)
{
if (string.Equals(context.TagName, "address",
StringComparison.OrdinalIgnoreCase) &&
output.Attributes.ContainsName("printable"))
{
var content = await output.GetChildContentAsync();
output.Content.SetHtmlContent(
$"<div>{content.GetContent()}</div>{_printableButton}");
}
}
}
上述 ProcessAsync
方法,會將提供給 SetHtmlContent 的 HTML,插入相符的 <address>
項目。 插入發生於:
- 執行內容的
TagName
屬性值等於address
。 - 對應的
<address>
項目具有printable
屬性。
例如,當處理下列 <address>
項目時,if
陳述式會評估為 True:
<address printable>
One Microsoft Way<br />
Redmond, WA 98052-6399<br />
<abbr title="Phone">P:</abbr>
425.555.0100
</address>
其他資源
意見反應
https://aka.ms/ContentUserFeedback。
即將登場:在 2024 年,我們將逐步淘汰 GitHub 問題作為內容的意見反應機制,並將它取代為新的意見反應系統。 如需詳細資訊,請參閱:提交並檢視相關的意見反應