Can I use a Tag Helper in a custom Tag Helper that returns html?

后端 未结 3 686
梦毁少年i
梦毁少年i 2020-12-30 23:39

I recently ran into a situation where I would like to use a tag helper within a tag helper. I looked around and couldn\'t find anyone else trying to do this, am I using a po

相关标签:
3条回答
  • 2020-12-30 23:54

    No you cannot. TagHelpers are a Razor parse time feature.

    One alternative is creating a TagHelper and manually invoking its ProcessAsync/Process method. Aka:

    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);
    
    0 讨论(0)
  • 2020-12-31 00:06

    If anyone's looking to reuse the built-in tag helpers from asp.net core, you can use the IHtmlGenerator instead. For reusing other types of tag helpers, I haven't found a simpler option then @N. Taylor Mullen answer

    Here is how to reuse the asp-action tag helper:

    [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);
        }
    }
    
    0 讨论(0)
  • 2020-12-31 00:10

    I don't know if this works for your scenario, but it is possible to inherit from the AnchorTagHelper and then do your customisations like this.

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

    Then you can just use this tag helper in your view with all the built-in goodness of the default AnchorTagHelper.

    <test asp-action="Index" asp-route-id="5"></test>
    
    0 讨论(0)
提交回复
热议问题