美文网首页
ASP.Net Core Web TagHelper 自定义

ASP.Net Core Web TagHelper 自定义

作者: 坚果jimbowhy | 来源:发表于2020-06-02 14:36 被阅读0次
TagHelper TagHelperComponent TagHelperComponentTagHelper

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());
}

相关文章

网友评论

      本文标题:ASP.Net Core Web TagHelper 自定义

      本文链接:https://www.haomeiwen.com/subject/wuuuzhtx.html