Linked Questions

Popular Questions

Instantiating and Invoking TagHelpers Manually

Asked by At

This is a follow up question to this question, which seems to be for an older ASP.NET Core version (I'm using 2.1).

I'm trying to call a TagHelper manually from within a TagHelper. Applying the Answer in the linked question above, the TagHelper.Process looks like so:

public override async void Process(TagHelperContext context, TagHelperOutput output)
{
    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);
}

Several compiler errors occur at this point.

cannot convert from 'System.Guid' to 'string'

No problem, I can cast to a String.

There is no argument given that corresponds to the required formal parameter 'value' of 'HtmlString.HtmlString(string)

Checking the MSDN page for the TagHelperOutput constructor, it seems it doesn't take an HtmlString anymore.

I changed that argument to a delegate fuction:

new TagHelperOutput("a", new TagHelperAttributeList(),
    (useCachedResult, encoder) => Task.Factory.StartNew<TagHelperContent>(
         () => new DefaultTagHelperContent()));

The last compiler error:

There is no argument given that corresponds to the required formal parameter 'generator' of 'AnchorTagHelper.AnchorTagHelper(IHtmlGenerator)

Hoping its an optional parameter, I passed in null:

var anchorTagHelper = new AnchorTagHelper(null);

It finally compiled - but this led to a null pointer exception on runtime:

Microsoft.AspNetCore.Mvc.TagHelpers.InputTagHelper.Process(TagHelperContext context, TagHelperOutput output)

My question is thus: how can I instantiate AnchorTagHelper so I can manually invoke TagHelpers in C#?

EDIT: I've DI'd IHtmlGenerator and got a more meaningful error message:

private IHtmlGenerator htmlGenerator;
public myAnchorTagHelper(IHtmlGenerator htmlGenerator) {
    this.htmlGenerator = htmlGenerator;
}

Value cannot be null. Parameter name: viewContext>

Microsoft.AspNetCore.Mvc.ViewFeatures.DefaultHtmlGenerator.GenerateActionLink(ViewContext viewContext, String linkText, String actionName, String controllerName, String protocol, String hostname, String fragment, Object routeValues, Object htmlAttributes) at Microsoft.AspNetCore.Mvc.TagHelpers.AnchorTagHelper.Process(TagHelperContext context, TagHelperOutput output) at EAGLEweb2020.Models.EAGLEinputTagHelper.Process(TagHelperContext context, TagHelperOutput output) in C:\Users\1135937\source\repos\EAGLEweb2020\EAGLEweb2020\Models\TagHelpers\EAGLEinputTagHelper.cs:line 66 at Microsoft.AspNetCore.Razor.TagHelpers.TagHelper.ProcessAsync(TagHelperContext context, TagHelperOutput output) at Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner.d__0.MoveNext()

But how can I DI a ViewContext?

EDIT 2:

Turns out ViewContext is a public property in AnchorTagHelper:

AnchorTagHelper inputTagHelper = new AnchorTagHelper(htmlGenerator);
inputTagHelper.ViewContext = viewContext;

But now the content is empty...

Related Questions