我可以在返回 html 的自定义 Tag Helper 中使用 Tag Helper 吗?

Posted

技术标签:

【中文标题】我可以在返回 html 的自定义 Tag Helper 中使用 Tag Helper 吗?【英文标题】:Can I use a Tag Helper in a custom Tag Helper that returns html? 【发布时间】:2017-02-02 19:10:24 【问题描述】:

我最近遇到了一种情况,我想在标签助手中使用标签助手。我环顾四周,找不到其他人尝试这样做,是我使用了糟糕的约定还是缺少文档?

例如。 标签助手 A 输出包含另一个标签助手的 html

例如。

[HtmlTargetElement("tag-name")]
public class RazorTagHelper : TagHelper

    public override void Process(TagHelperContext context, TagHelperOutput output)
    
        StringBuilder sb = new StringBuilder();
        sb.Append("<a asp-action=\"Home\" ");
        output.Content.SetHtmlContent(sb.ToString());
    

有没有办法让我处理来自 C# 的 &lt;a asp-action&gt; &lt;/a&gt; 标签助手?还是用标签助手重新处理输出的 HTML?

【问题讨论】:

这有什么帮助吗? ***.com/questions/32692857/… @Vlince 感谢您的链接,但不,这不是我想要做的,我想要一个输入标签,没有其他嵌套标签。我真正想做的是从另一个标签助手中调用一个标签助手。 您是否正在寻找View Components? 视图组件可以在这种情况下工作,但是,如果可能的话,我真的很想保留标签助手的 HTML 式语法 从 ASP.NET 2.1 开始,一些类已经改变了。请参阅此问答:***.com/questions/54582450/… 【参考方案1】:

不,你不能。 TagHelpers 是 Razor 解析时间功能。

另一种方法是创建 TagHelper 并手动调用其 ProcessAsync/Process 方法。又名:

var anchorTagHelper = new AnchorTagHelper

    Action = "Home",
;
var anchorOutput = new TagHelperOutput("a", new TagHelperAttributeList(), (useCachedResult, encoder) => new HtmlString());
var anchorContext = new TagHelperContext(
    new TagHelperAttributeList(new[]  new TagHelperAttribute("asp-action", new HtmlString("Home")) ),
    new Dictionary<object, object>(),
    Guid.NewGuid());
await anchorTagHelper.ProcessAsync(anchorContext, anchorOutput);
output.Content.SetHtmlContent(anchorOutput);

【讨论】:

真是一团糟,如果这是唯一的方法,那就太不幸了。我将把这个问题留一天左右,只是为了确认这是我必须这样做的方式。如果没有其他答案,我当然会接受。谢谢 我认为这个答案很棒。对于所有高级的东西,视图组件是要走的路。对于您的情况,直接使用UrlHelper 可能会更好@JacobLinney @ChristianGollhardt 感谢您的意见和建议;我只是想确认没有更好的方法可以做到这一点。这不是我的实际用例,只是一个抽象。【参考方案2】:

我不知道这是否适用于您的场景,但可以从 AnchorTagHelper 继承,然后像这样进行自定义。

public class TestTagHelper : AnchorTagHelper

    public TestTagHelper(IHtmlGenerator htmlGenerator) : base(htmlGenerator)  

    public async override Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
    
        // Replaces <test> with <a> tag
        output.TagName = "a"; 
        // do custom processing
        output.Attributes.SetAttribute("class", "custom-class");
        // let the base class generate the href 
        // note the base method may override your changes so it may be  
        // preferable to call it first instead of last.
        await base.ProcessAsync(context, output);
    

然后你可以在你的视图中使用这个标签助手,并使用默认 AnchorTagHelper 的所有内置优点。

<test asp-action="Index" asp-route-id="5"></test>

【讨论】:

公平警告,首先应该调用 base.ProcessAsync,因为基本标签助手可以在调用之前轻松覆盖您对输出所做的任何更改。例如使用 SetHtmlContent()。一旦你调用了基本代码,你就可以在已经存在的地方添加你的补充。【参考方案3】:

如果有人希望重用 asp.net 核心的内置标签助手,您可以改用 IHtmlGenerator。对于重用其他类型的标签助手,我没有找到比@N 更简单的选项。泰勒马伦回答

这里是如何重用 asp-action 标签助手:

[HtmlTargetElement("helplink")]
public class RazorTagHelper : TagHelper

    private readonly IHtmlGenerator _htmlGenerator;

    public RazorTagHelper(IHtmlGenerator htmlGenerator)
    
        _htmlGenerator = htmlGenerator;
    

    [ViewContext]
    public ViewContext ViewContext  set; get; 

    public override void Process(TagHelperContext context, TagHelperOutput output)
    
        output.TagName = "div";
        output.TagMode = TagMode.StartTagAndEndTag;
        var actionAnchor = _htmlGenerator.GenerateActionLink(
            ViewContext,
            linkText: "Home",
            actionName: "Index",
            controllerName: null,
            fragment: null,
            hostname: null,
            htmlAttributes: null,
            protocol: null,
            routeValues: null
            );
        var builder = new HtmlContentBuilder();
        builder.AppendHtml("Here's the link: ");
        builder.AppendHtml(actionAnchor);
        output.Content.SetHtmlContent(builder);
    

【讨论】:

以上是关于我可以在返回 html 的自定义 Tag Helper 中使用 Tag Helper 吗?的主要内容,如果未能解决你的问题,请参考以下文章

Django的自定义标签

如何通过评论折叠CLION中的自定义区域?

具有标签的 DataRows 的自定义 DataTable

对标签强制执行的自定义策略

使用 IIS ApplicationInitialization remapManagedRequestsTo 功能时返回用于提供静态 html 的自定义响应代码?

iOS自定义表情的实现