1 准备工作
继续使用上一章项目代码,修改Startup.cs。
public void ConfigureServices(IServiceCollection services) {
services.AddDbContext<DataContext>(opts => {
opts.UseSqlServer(Configuration[
"ConnectionStrings:ProductConnection"]);
opts.EnableSensitiveDataLogging(true);
});
services.AddControllersWithViews().AddRazorRuntimeCompilation();
services.AddRazorPages().AddRazorRuntimeCompilation();
services.AddSingleton<CitiesData>();
}
public void Configure(IApplicationBuilder app, DataContext context) {
app.UseDeveloperExceptionPage();
app.UseStaticFiles();
app.UseRouting();
app.UseEndpoints(endpoints => {
endpoints.MapControllers();
endpoints.MapDefaultControllerRoute();
endpoints.MapRazorPages();
});
SeedData.SeedDatabase(context);
}
修改Views/Home/index.cshtml。
@model Product
@{
Layout = "_SimpleLayout";
}
<table class="table table-striped table-bordered table-sm">
<thead>
<tr>
<th colspan="2">Product Summary</th>
</tr>
</thead>
<tbody>
<tr><th>Name</th><td>@Model.Name</td></tr>
<tr>
<th>Price</th>
<td>@Model.Price.ToString("c")</td>
</tr>
<tr><th>Category ID</th><td>@Model.CategoryId</td></tr>
</tbody>
</table>
在Views/Shard文件夹下添加_SimpLayout.cshtml。
<!DOCTYPE html>
<html>
<head>
<title>@ViewBag.Title</title>
<link href="/lib/twitter-bootstrap/css/bootstrap.min.css" rel="stylesheet" />
</head>
<body>
<div class="m-2">
@RenderBody()
</div>
</body>
</html>
请求http://localhost:5000/home。
2 创建标签助手
下面介绍创建和应用标签助手的过程,为tr元素设置引导css类如下。
<tr tr-color="primary">
<th colspan="2">Product Summary</th>
</tr>
转化为这样。
<tr class="bg-primary text-white text-center">
<th colspan="2">Product Summary</th>
</tr>
2.1 定义标签助手类
创建TagHelpers文件夹,添加TrTagHelper.cs文件。
public class TrTagHelper : TagHelper
{
public string BgColor { get; set; } = "dark";
public string TextColor { get; set; } = "white";
public override void Process(TagHelperContext context,
TagHelperOutput output)
{
output.Attributes.SetAttribute("class",
$"bg-{BgColor} text-center text-{TextColor}");
}
}
标签助手是从 TagHelper 类派生的,该类在 Microsoft.AspNetCore.Razor.TagHelpers 名称空间中定义。TagHelper 类定义了一个 Process 方法,它被子类覆盖以实现转换元素的行为。
标签助手的名称组合了它转换的元素的名称,后跟 TagHelper。在本例中,类名 TrTagHelper表示这是一个操作tr 元素的标签助手。
(1)接收上下文数据
标签助手通过 TagHelperContext 类的实例接收关于它们正在转换的元素的信息,这个实例为 Process 方法的参数接收,如下定义了描述的属性。
- AllAttributes:此属性返回一个特性的只读字典,其中包含应用于被转换元素的特性,按名称和索引排序。
- Items:此属性返回一个字典,该字典用于在标签助手之间进行协调。
- Uniqueld:此属性返回被转换元素的唯一标识符。
(2)生成输出
Process 方法通过配置作为参数接收的 TagHelperOutput 对象来转换元素。TagHelperOutput象首先描述出现在视图中的 HTML, 元素,然后通过以下描述的属性和方法进行修改。
- TagName:此属性用于获取或设置输出元素的标记名。
- Attributes:此属性返回一个包含输出元素属性的字典。
- Content:此属性返回一个 TagHelperContent对象,该对象用于设置元素的内容。
- GetChildContentAsync():这个异步方法提供了对将要转换的元素内容的访问。
- PreElement:该属性返回一个 TagHelperContext对象,该对象用于在输出元素之前在视图中插入内容。
- PostElement:该属性返回一个 TagHelperContext 对象,该对象用于在输出元素之后在视图中插入内容。
- PreContent:此属性返回一个 TagHelperContext 对象,用于在输出元素的内容之前插入内容。
- PostContent:此属性返回一个 TagHelperContext对象,用于在输出元素的内容之后插入内容。
- TagMode:此属性指定如何使用 TagMode 枚举的值写入输出元素。
- SupressOuput():调用该方法会从视图中排除一个元素。
在 TrTagHelper 类中,使用 Attributes 字典向指定引导样式的 HTML 元素添加了一个 class 属性,包括 BgColor 和 TextColor 属性的值。其效果是,可通过将 bg-color 和 text-color 属性设置为引导名称(如 primary、info 和 danger)来指定 tr 元素的背景颜色。
2.2 注册标签助手
在使用标签助手类之前,它们必须在@addTagHelper 指令中注册。标签助手可以应用到的组视图或页面取决于使用@addTagHelper 指令的位置。
对于单个视图或页面,指令出现在CSHTML文件中。要使标签助手更广泛地可用,可以将其添加到视图导入文件中。
希望本章创建的标签助手在应用程序的任何地方都可用,这意味着@addTagHelper 指令添加到 Views 和 Pages 文件夹的 _ViewImports.cshtml 文件中。在前一章中用于应用视图组件的 vc 元素是一个标签助手,这就是启用标签助手所需的指令位于 _ViewImports.cshtm 文件的原因。
@addTagHelper *,MyWebApp
参数的第一部分指定标签助手类的名称,并支持通配符,第二部分指定定义它们的程序集的名称。@addTagHelper 指令使用通配符选择 MyWebApp 程序集中的所有名称空间,其效果是在项目中任何地方定义的标签助手都可在任何控制器视图中使用。Razor Pages 文件夹的Viewlmports.cshtm 文件中有一个相同的语句。
2.3 使用标签助手
使用标签助手转换元素,将属性添加到tr元素,它将应用标签助手。Home 文件夹的 Index.cshtml 文件中使用标签助手。浏览器请求 http://ocalhost:5000/home。
<tr bg-color="info" text-color="white">
<th colspan="2">Product Summary</th>
</tr>
应用属性的tr元素进行了转换,但这不是显示的唯一更改。默认情况下,标签助手应用于特定类型的所有元素,这意味着视图中的所有tr元素都使用标签助手类中定义的默认值进行转换,因为没有定义任何特性。
2.4 缩小标签助手的范围
可使用 HTMLTargetElement 元素控制由标签助手转换的元素范围,TrTagHelper.cs 文件中缩小范围。
[HtmlTargetElement("tr", Attributes = "bg-color,text-color", ParentTag = "thead")]
public class TrTagHelper : TagHelper
HTMLTargetElement 属性描述了应用标签助手的元素。第一个参数指定元素类型,并支持表以下描述的其他命名属性。
- Attributes:指定标签助手应仅用于具有一组给定属性(以逗号分隔)的元素。以星号编结尾的属性名称将被视为前缀,这样 bg-*将匹配 bg-color、bg-size 等。
- ParentTag:指定标签助手应仅应用于给定类型元素中包含的元素。
- TagStructure:指定标签助手仅应用于其标记结构对应于TagStructure 枚举中给定值的元素,该枚举定义了Unspecified、NormalOrSelfClosing 和 WithoutEndTag。
Amibutes 属性支持 CSS 属性选择器语法,这样[bg-color]匹配具有 bg-color 属性的元素,[bg-color primary]匹配 bg-color 属性值为 primary 的元素,[bg-color^=p]配 bg-color 属性值以p开头的元素。
代码中应用于标签助手的属性匹配如下tr 元素,包含 bg-color 和 text-color 属性,父元素是 thead。
浏览器请求http://localhost:5000/home/index/1,标签助手的范围缩小了。
2.5 扩展标签助手的范围
HTMLTargetElement 属性还可用于扩大标签助手的范围,以便匹配更大范围的元素。这是通过将属性的第一个参数设置为星号(字符)来实现的,匹配任何元素。
[HtmlTargetElement("*", Attributes = "bg-color,text-color")]
使用星号时必须小心,因为很容易匹配过大范围,并选择不应该转换的元素。更安全的中间方法是为每类元素应用 HTMLTargetElement 属性。
[HtmlTargetElement("tr", Attributes = "bg-color,text-color")]
[HtmlTargetElement("td", Attributes = "bg-color")]
修改Home 文件夹的 Index.cshtml 文件中添加属性。并使用浏览器请求 http:/localhost:5000/home/index/1。
<td bg-color="dark">@Model.Price.ToString("c")</td>
3 高级标签助手功能
3.1 创建快捷元素
标签助手并不仅限于转换标准 HTML 元素,还可用常用内容替换定制元素。这是一个有用的特性,可使视图更简洁,意图更明显。为演示这一点,Index.cshtml 用定制的 HTML 元素替换了 thead 元素。
<tablehead bg-color="dark">Product Summary</tablehead>
将一个名为TableHeadTagHelper.cs 的类添加到TagHelpers 文件夹。
[HtmlTargetElement("tablehead")]
public class TableHeadTagHelper : TagHelper
{
public string BgColor { get; set; } = "light";
public override async Task ProcessAsync(TagHelperContext context,
TagHelperOutput output)
{
output.TagName = "thead";
output.TagMode = TagMode.StartTagAndEndTag;
output.Attributes.SetAttribute("class",
$"bg-{BgColor} text-white text-center");
string content = (await output.GetChildContentAsync()).GetContent();
output.Content.SetHtmlContent($"<tr><th colspan=\"2\">{content}</th></tr>");
}
}
这个标签助手是异步的,并且覆盖了ProcessAsync方法,这样它就可以访问它转换的元素的现有内容。ProcessAsync方法使用TagHelperOuput对象的属性来生成一个完全不同的元素:TagName属性用于指定thead元素,TagMode属性用于指定使用开始和结束标记编写元素。Attibutes.SetAttribute方法用于定义类属性,Content属性用于设置元素内容。
元素的现有内容是通过异步GetchidContentAsync方法获得的,该方法返回TagHelperconent对象。这与TaeHeperOuput.Content属性返回的对象相同,并允许使用相同类型,通如下描述的方法来检査和更改元素的内容。
- GetContent():此方法以字符串形式返回 HTML 元素的内容。
- SetContent(text):此方法设置输出元素的内容。对字符串参数进行编码,以便安全地包含在Html素中。
- SetHtmlContent(html):此方法设置输出元素的内容。假设字符串参数是安全编码的。应当谨慎使用。
- Append(text):此方法安全地编码指定的字符串,并将其添加到输出元素的内容中。
- AppendHtml(html):此方法将指定的字符串添加到输出元素的内容中,而不执行任何编码。应当谨慎使用。
- Clear():此方法删除输出元素的内容。
元素的现有内容通过 GetContent 元素读取,然后使用 SetHtmlconm方法设置它。效果是在 tr和 th 元素中对已转换元素中的现有内容换行。重启 并导航到 http://localhost:5000/home/index/1, 就会看到标签助手的效果。
<tablehead bg-color="dark">Product Summary</tablehead>
以上代码将被转换为:
<thead class="bg-dark text-white text-center">
<tr>
<th colspan="2">Product Summary</th>
</tr>
</thead>
注意,转换后的元素不包括 bg-color 属性。与标签助手定义的属性匹配的属性将从输出元素中删除;如有必要,则必须显式地重新定义它们。
3.2 以编程方式创建元素
在生成新的 HTML 元素时,可以使用标准的 C#字符串格式来创建所需的内容,这就是在 TableHeadTagHelper.cs 中采用字符串的方法。这样做有效但需要密切注意以避免拼写错误。
更健壮的方法是使用 TagBuilder类,它是在 Microsot.AspNetCore.Mvc.Rendering 名称空间中定义的,并允许以更结构化的方式创建元素。 TaglelperContent 方法接收 TagBuilde 对象,这将便于在标签助手中创建 HTML 内容,修改TableHeadTagHelper.cs中ProcessAsync方法,如下所示。
......
string content = (await output.GetChildContentAsync()).GetContent();
//output.Content.SetHtmlContent($"<tr><th colspan=\"2\">{content}</th></tr>");
TagBuilder header = new TagBuilder("th");
header.Attributes["colspan"] = "2";
header.InnerHtml.Append(content);
TagBuilder row = new TagBuilder("tr");
row.InnerHtml.AppendHtml(header);
output.Content.SetHtmlContent(row);
3.3 追加、附加内容和元素
TagHelperOutput 类提供了四个属性,可以很容易地将新内容注入视图中,以便包用元素或元素内容。
- PreElement:此属性用于在目标元素之前向视图中插入元素
- PostElement:此属性用于在目标元素之后向视图中插入元素
- PreContent:此属性用于在任何现有内容之前将内容插入目标元素
- PostContent:此属性用于在任何现有内容之后将内容插入目标元素
接下来解释如何在目标元素周围和内部插入内容。
(1)在输出元素周围插入内容
前两个 TagHelperOuput 属性是 PreElement 和 PostElement,它们用于在输出元素之前和之向视图插入元素。为演示这些属性的用法,将一个名为 WrapperTagHelper.cs 的类文件添加到 TagHelpers 文件夹中。
[HtmlTargetElement("*", Attributes = "[wrap=true]")]
public class ContentWrapperTagHelper : TagHelper
{
public override void Process(TagHelperContext context, TagHelperOutput output)
{
TagBuilder elem = new TagBuilder("div");
elem.Attributes["class"] = "bg-primary text-white p-2 m-2";
elem.InnerHtml.AppendHtml("wrapper");
output.PreElement.AppendHtml(elem);
output.PostElement.AppendHtml(elem);
}
}
这个标签助手转换 wrap属性值为 true 的元素,使用 preElement 和 PostElement 属性在蠊元素之前和之后添加 div元素。将一个元素添加到由标签助手转换的索引视图中。
在Home/Index.cshtml视图中添加如下。
<div class="m-2" wrap="true">Inner Content</div>
使用浏览器请求 http://localhost:5000/home/index/1。 响应包括转换后的元素将是这样。
<div class="bg-primary text_white p-2 m-2">wrapper</div>
<div class="m-2" wrap="true">Inner Content</div>
<div class="bg-primary text-white p-2 m-2">wrapper</div>
(2)在输出元素中插入内容
PreContent 和 PostContent属性用于在输出元素中围绕原始内容插入内容。为演示这个特性将一个名为 HighlightTagHelper.cs 的类文件添加到 TagHelpers 文件夹中。
[HtmlTargetElement("*", Attributes = "[highlight=true]")]
public class HighlightTagHelper : TagHelper
{
public override void Process(TagHelperContext context, TagHelperOutput output)
{
output.PreContent.SetHtmlContent("<b><i>");
output.PostContent.SetHtmlContent("</i></b>");
}
}
这个标签助手在输出元素的内容周围插入b和i元素。如下代码将wrap属性添加到Inde视图中的一个表格单元格中。
<tr><th>Name</th><td highlight="true">@Model.Name</td></tr>
使用浏览器请求 http://localhost:5000/home/index/1。 响应包括转换后的元素将是这样。
<td highlight="true"><b><i>Kayak</i></b></td>
3.4 获取视图上下文数据
标签助手的一个常见用途是转换元素,使它们包含当前请求或视图模型/页面模型的详细信息,这需要访问上下文数据。要创建这种类型的标签助手,将一个名为 RouteDataTagHelper.cs 的文件添加到 TagHelpers 文件夹。
[HtmlTargetElement("div", Attributes = "[route-data=true]")]
public class RouteDataragHelper : TagHelper
{
[ViewContext]
[HtmlAttributeNotBound]
public ViewContext Context { get; set; }
public override void Process(TagHelperContext context, TagHelperOutput output)
{
output.Attributes.SetAttribute("class", "bg-primary m-2 p-2");
TagBuilder list = new TagBuilder("ul");
list.Attributes["class"] = "list-group";
RouteValueDictionary rd = Context.RouteData.Values;
if (rd.Count > 0)
{
foreach (var kvp in rd)
{
TagBuilder item = new TagBuilder("li");
item.Attributes["class"] = "list-group-item";
item.InnerHtml.Append($"{kvp.Key}:{kvp.Value}");
list.InnerHtml.AppendHtml(item);
}
output.Content.AppendHtml(list);
}
else
{
output.Content.Append("No route data");
}
}
}
标签助手转换具有 route-data 属性(其值为 true)的 div 元素,并使用路由系统获得的段变量列表填充输出元素。
为获取路由数据,添加了一个名为 Context 的属性,并用两个特性装饰它。
ViewContext 属性的值应该在创建标签助手类的新实例时分配一个 ViewConte对象,它提供了正在呈现的视图的详细信息,包括路由数据。
如果在 div 元素上定义了匹配的属性,HTMLAttributeNotBound 属性将阻止为该属性分配值。
向主控制器的 Index.cshtml 视图添加了一个元素,这个元素由新的标签助手进行转换。使用浏览器请求 http://localhost:5000/home/index/1。 响应将包括路由系统匹配的段变量的列表。
<div route-data="true"></div>
3.5 使用模型表达式
标签助手可以操作视图模型,裁剪它们执行的转换或它们创建的输出。要了解这个特性是何工作的,将一个名为 ModelRowTagHielpercs 的类文件添加到 TagHelpers 文件夹中。
[HtmlTargetElement("tr", Attributes = "for")]
public class ModelRowTagHelper : TagHelper
{
public string Format { get; set; }
public ModelExpression For { get; set; }
public override void Process(TagHelperContext context, TagHelperOutput output)
{
output.TagMode = TagMode.StartTagAndEndTag;
TagBuilder th = new TagBuilder("th");
th.InnerHtml.Append(For.Name);
output.Content.AppendHtml(th);
TagBuilder td = new TagBuilder("td");
if (Format != null && For.Metadata.ModelType == typeof(decimal))
{
td.InnerHtml.Append(((decimal)For.Model).ToString(Format));
}
else
{
td.InnerHtml.Append(For.Model.ToString());
}
output.Content.AppendHtml(td);
}
}
这个标签助手转换具有 for 特性的 tr 元素。这个标签助手的重要部分是 For属性的ModelExpression类型,该属性用于接收 for 特性的值。
希望对视图模型的一部分进行操作时,将使用 ModelExpression 类,最简单的解释方法是向前跳转并显示如何在视图中应用标签助手。修改Home/Index.cshtml。
<tbody>
<tr for="Name" />
<tr for="Price" format="c" />
<tr for="CategoryId" />
</tbody>
for 特性的值是视图模型类定义的属性的名称。在创建标签助手时,检测 For 属性的类型,并分配一个描述所选属性的 ModelExpression 对象。
对于示例标签助手,使用了三个值得描述的基本功能。第一个是获得模型属性的名称(For.Name),这样就可以把它包含在输出元素中。第二个功能是获取模型属性的类型(For.Metadata.ModelType),这样可以决定是否格式化值。第三个功能是获取属性的值(For.Model),以便将其包含在响应中。
3.6 标签助手之间的协调
TagHelperContext.Items 属性提供一个字典,用于操作元素及其后代的标签助手。为了演示Items 集合的使用,将一个名为 CoordinatingTagHelpers.cs 的类文件添加到 TagHelpers 文件夹中。
[HtmlTargetElement("tr", Attributes = "theme")]
public class RowTagHelper : TagHelper
{
public string Theme { get; set; }
public override void Process(TagHelperContext context, TagHelperOutput output)
{
context.Items["theme"] = Theme;
}
}
[HtmlTargetElement("th")]
[HtmlTargetElement("td")]
public class CellTagHelper : TagHelper
{
public override void Process(TagHelperContext context, TagHelperOutput output)
{
if (context.Items.ContainsKey("theme"))
{
output.Attributes
.SetAttribute("class", $"bg-{context.Items["theme"]} text-white");
}
}
}
第一个标签助手对具有 theme 属性的 tr 元素进行操作。协调标签助手可转换它们自己的元素但本示例只是将 theme 属性的值添加到 Itens 字典中,以便对操作t 元素中包含的元素的标签助手可用。第二个标签助手对 t 和 td 元素进行操作,并使用 Items 字典中的 theme 值为其输出元素设置引导样式。
向主控制器的 Index 视图添加了应用协调标签助手的元素。
<tr theme="primary">
<th>Name</th>
<td>@Model.Name</td>
</tr>
<tr theme="secondary">
<th>Price</th>
<td>@Model.Price.ToString("c")</td>
</tr>
<tr theme="info">
<th>Category</th>
<td>@Model.CategoryId</td>
</tr>
使用测览器请求 himp://localhost:5000/home。theme 元素的值已经从一个标签助手传递到另一个标签助手,并且应用颜色主题时不需要每个被转换的元素上定义属性。
3.7 抑制输出元素
通过调用作为 Process 方法参数接收的 TagHelperOutput对象上的 SuppressOutput 方法,可使用标签助手来防止元素包含在 HTM 响应中。
向主控制器的 Imdex 视图加了一个元素,只有在视图模型的 Price 属性超过指定值时才应该显示该元素。
<div show-when-gt="500" for="Price">
<h5 class="bg-danger text-white text-center p-2">
Warning: Expensive Item
</h5>
</div>
show-when-gt属性指定了 div 元素应在其上显示的值,而 for 属性选择要检査的模型属性。要创建管理元素(包括响应)的标签助手,将一个名为SelectiveTagHelper.cs 的类文件添加到TagHelpers 文件夹。
[HtmlTargetElement("div", Attributes = "show-when-gt, for")]
public class SelectiveTagHelper : TagHelper
{
public decimal ShowWhenGt { get; set; }
public ModelExpression For { get; set; }
public override void Process(TagHelperContext context, TagHelperOutput output)
{
if (For.Model.GetType() == typeof(decimal)
&& (decimal)For.Model <= ShowWhenGt)
{
output.SuppressOutput();
}
}
}
除非超过阈值,否则标签助手使用模型表达式访问属性并调用SuppressOutput 方法。要查看效果,使用浏览器请求 http://localhost:5000/home/index/1 和 http://localhost:5000/home/index/5。 第一个 URL 选择的产品的 Price 属性值小于阈值,因此该元素被抑制。第二个 URI, 选择的产品的 Price 属性值超过了阈值,因此显示该元素。
4 使用标签助手组件
标签助手组件提供了将标签助手用作服务的另一种方法。当需要设置标签助手来支持另一个服务或中间件组件时可能非常有用。
4.1 创建标签助手组件
标签助手组件是从 TagHelperComponent 类派生的,该类提供了与TagHelper基类类似的Api。
在 TagHelpers 文件夹下添加 TimeTagHelperComponent.cs 文件。
public class TimeTagHelperComponent : TagHelperComponent
{
public override void Process(TagHelperContext context, TagHelperOutput output)
{
string timestamp = DateTime.Now.ToLongTimeString();
if (output.TagName == "body")
{
TagBuilder elem = new TagBuilder("div");
elem.Attributes.Add("class", "bg-info text-white m-2 p-2");
elem.InnerHtml.Append($"Time: {timestamp}");
output.PreContent.AppendHtml(elem);
}
}
}
标签助手组件不指定它们转换的元素,并为已经配置标签助手组件特性的每个元素调用Process方法。默认情况下,应用标签助手组件来转换 head 和 body 元素。这意味着标签助手类必须检査输出元素的 TagName 属性,以确保它们只执行预期的转换。
以上标签助手组件查找 body 元素,并使用 PreContent 属性在元素的其余内容之前插入包含时间戳的 div 元素。
在Startup.cs中注册标签助手组件。
services.AddTransient<ITagHelperComponent, TimeTagHelperComponent>();
AddTransient 方法用于确保使用标签助手组件类的实例来处理每个请求。要查看标签助手组件的效果,使用浏览器请求 http://localhost:5000/home。 该响应以及来自应用程序的其他所有HTML响应包含由标签助手组件生成的内容。
4.2 展开标签助手的元素选择
默认情况下,标签助手组件只处理 head 和 body 元素,但可通过创建一个派生自TagHelperComponentTagHelper 的类来选择其他元素。
TagHelpers 文件夹下添加 TableFooterTagHelperComponemt.cs 类。
[HtmlTargetElement("table")]
public class TableFooterSelector : TagHelperComponentTagHelper
{
public TableFooterSelector(ITagHelperComponentManager mgr, ILoggerFactory log)
: base(mgr, log) { }
}
public class TableFooterTagHelperComponent : TagHelperComponent
{
public override void Process(TagHelperContext context, TagHelperOutput output)
{
if (output.TagName == "table")
{
TagBuilder cell = new TagBuilder("td");
cell.Attributes.Add("colspan", "2");
cell.Attributes.Add("class", "bg-dark text-white text-center");
cell.InnerHtml.Append("Table Footer");
TagBuilder row = new TagBuilder("tr");
row.InnerHtml.AppendHtml(cell);
TagBuilder footer = new TagBuilder("tfoot");
footer.InnerHtml.AppendHtml(row);
output.PostContent.AppendHtml(footer);
}
}
}
TableFooterSelector 类派生自TagHelperComponentTagHelper,并使用 HTMLTargetElement 属性装饰它,该属性扩展了由应用程序的标签助手组件处理的元素范围。在本例中,属性选择 table 元素。
在同一个文件中定义的 TableFooterTagHelperComponent 类是一个标签助手组件,它通过添加tfoot 元素来转换表元素,tfoot 元素表示表的页脚。
标签助手组件必须注册为服务来接收转换的元素。
services.AddTransient<ITagHelperComponent, TableFooterTagHelperComponent>();
使用浏览器请求呈现表的 URL,如 http://localhost:5000/home。 每个表将包含一个表的页脚。
标签:Core,ASP,标签,元素,助手,output,NET,public,属性 From: https://www.cnblogs.com/nullcodeworld/p/18219982