ASP.Net Core Web TagHelper 自定义
![](https://img.haomeiwen.com/i5509701/979b1fe1dc247f3a.png)
TagHelper 自定义
来,我给大家讲个笑话:
TagHelper TagHelperComponent TagHelperComponentTagHelper
ASP.Net 引入的 TagHelper 助手标签是一个好东西,比 HtmlHelper 是不同一个年代的东西。
ASP.NET Core 2 带来的TagHelperComponent
组件是动态地向 HTML 中添加内容最完美的选择。为了能像助手标签一样使用助手标签组件,需要通过 TagHelperComponentTagHelper
来实现,都知道,这个命名非常令人困惑。
ASP.NET Core 在 Microsoft.AspNetCore.Mvc.Razor.TagHelpers 提供了两个内置助手标签组件 TagHelperComponent
, 即 HeadTagHelper 和 BodyTagHelper 来将内容插入 <head>
或 <body>
。并且可在 MVC 和 Razor 页面中使用,组件不需要在 _ViewImports.cshtml
中注册应用。
继承自 TagHelperComponentTagHelper
的类型也就是一个 Tag Helper,不过它将执行与之匹配的 TagHelperComponent
组件。官方文档只有一句说明,按指定顺序将 TagHelperComponent
添加到组件集合并初始化:
Initializes and processes the ITagHelperComponents added to the Components in the specified order.
标签组件采用 Pascal 大小写格式将类和属性名将转换为各自相应的短横线连接格式。 比如,要使用 MailTo 属性,请使用 <email mail-to="value"/>
等效项。
未显式标识 [HtmlTargetElement] 属性的助手标签,按 Pascal 大小写格式转换,EmailToTagHelper 对应 <email-to />
,后缀 TagHelper 是可选的,只要继承 TagHelper 基类即可 。 特性 NormalOrSelfClosing 和
WithoutEndTag 分别指明 HTML 的自闭合,或无终结标记。
using System;
using System.ComponentModel;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Razor.TagHelpers;
using Microsoft.AspNetCore.Razor.TagHelpers;
using Microsoft.Extensions.Logging;
namespace AppWeb.TagHelpers
{
[HtmlTargetElement("me")] // <me asp-href="demo.css">Test Me</me>
[EditorBrowsable(EditorBrowsableState.Never)]
public class MyTagComponentTagHelper : TagHelperComponentTagHelper
{
public MyTagComponentTagHelper(
ITagHelperComponentManager manager,
ILoggerFactory loggerFactory) : base(manager, loggerFactory)
{
//...
}
public override async Task ProcessAsync(TagHelperContext context,
TagHelperOutput output)
{
TagHelperContent childContent = await output.GetChildContentAsync();
output.TagName = "b";
var text = childContent.GetContent().ToUpper()+DateTime.Now.ToString(" ss-fff");
output.Content.AppendHtml(text);
Console.WriteLine("TagHelperComponentTagHelper....{0}", context.TagName);
}
}
public class LinkStyleTagComponent : TagHelperComponent
{
private string _style =
@"<link rel=""stylesheet"" href=""@"" />";
public override int Order => 1;
public LinkStyleTagComponent()
{
// ...
}
public override async Task ProcessAsync(TagHelperContext context,
TagHelperOutput output)
{
TagHelperContent childContent = await output.GetChildContentAsync();
if (string.Equals(context.TagName, "head", // body or head
StringComparison.OrdinalIgnoreCase))
{
var style = _style.Replace("@", "/css/demo.css");
output.PostContent.AppendHtml(style);
}
// Console.WriteLine("TagHelperComponent....{0}", context.TagName);
}
}
// [HtmlTargetElement("email", TagStructure = TagStructure.NormalOrSelfClosing)]
// [HtmlTargetElement("email", TagStructure = TagStructure.WithoutEndTag)]
[HtmlTargetElement("email")]
public class EmailTagHelper : TagHelper
{
// passed by <email to="name@domain.com" />
public string To { get; set; }
public EmailTagHelper()
{
//...
}
public override void Process(TagHelperContext context, TagHelperOutput output)
{
output.TagName = "a"; // Replaces <email> with <a> tag
string href = "mailto:"+To;
output.Attributes.SetAttribute("href", href);
// string inner = output.Content.GetContent();
output.Content.SetContent($"<i>{To}</i>");
output.TagMode = TagMode.StartTagAndEndTag; // SelfClosing or StartTagOnly
// output.SuppressOutput();
}
public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
{
output.TagName = "a"; // Replaces <email> with <a> tag
var childContent = await output.GetChildContentAsync();
string content = childContent.GetContent();
output.Attributes.SetAttribute("href", "mailto:" + To);
output.Content.SetHtmlContent($"<b>{content}</b>");
// foreach(var a in output.Attributes)
// {
// Console.WriteLine("TagHelper {0}:{1}", a.Name, a.Value);
// }
}
}
}
如果多个自定义助手标签处理同一种标签时,可以通过 IsModified 来判断内容是否经过修改,如果是则从输出缓冲区获取内容:
var childContent = output.Content.IsModified ? output.Content.GetContent() :
(await output.GetChildContentAsync()).GetContent();
输出流可用的方法:
output.Attributes.RemoveAll("bold");
output.PreContent.SetHtmlContent("<strong>"); 在本体前附加
output.Content.SetHtmlContent("REPLACE"); 替换本体
output.PostContent.SetHtmlContent("</strong>"); 在本体后附加
output.SuppressOutput();
有三种方法注册助手组件,可以在 Startup 中注册组件服务:
using System.ComponentModel;
using Microsoft.AspNetCore.Razor.TagHelpers;
using Microsoft.AspNetCore.Mvc.Razor.TagHelpers;
services.AddTransient<ITagHelperComponentTagHelper, MyTagComponentTagHelper>();
services.AddTransient<ITagHelperComponent, LinkStyleComponent>();
在 cshtml 中注册助手标签,或者在 _Imports.cshtml
文件中,注意格式指定 * 表示引入后面程序集的所有助手标签,注意是程序集不是命名空间,注意不要在 @addTagHelper 末尾加分号:
@using Microsoft.AspNetCore.Mvc.Razor.TagHelpers
@inject ITagHelperComponentManager manager
@addTagHelper *, AppWeb
@addTagHelper AppWeb.TagHelpers.EmailTagHelper, AppWeb
@{
ViewData["Title"] = "Edit";
manager.Components.Add(new LinkStyleComponent());
}
在 PageMode 中注册助手标签:
using System.ComponentModel;
using Microsoft.AspNetCore.Mvc.Razor.TagHelpers;
using Microsoft.AspNetCore.Razor.TagHelpers;
using Microsoft.Extensions.Logging;
private readonly ITagHelperComponentManager _tagHelperComponentManager;
public EditModel(
ITagHelperComponentManager tagHelperComponentManager,
ILoggerFactory loggerFactory)
{
_tagHelperComponentManager = tagHelperComponentManager;
_tagHelperComponentManager.Components.Add(new LinkStyleComponent());
}