Instantiating and Invoking TagHelpers Manually

两盒软妹~` 提交于 2020-01-06 07:59:30

问题


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...


回答1:


Hi I was going through this and you got stuck at the ViewContext and the Output. I have done a similar project. Here's the code, hope it helps.

[HtmlTargetElement(ParentAnchorTag)]
public class ParentActionTagHelper : TagHelper
{
    private const string ParentAnchorTag = "p-a";

    [HtmlAttributeNotBound]
    [ViewContext]
    public ViewContext viewContext { get; set; }

    private readonly IHtmlGenerator _htmlGenerator;

    public ParentActionTagHelper(IHtmlGenerator htmlGenerator)
    {
        _htmlGenerator = htmlGenerator;
    }
    public override void Process(TagHelperContext context, TagHelperOutput output)
    {
        output.TagName = "div";

        var anchorTagHelper = new AnchorTagHelper(_htmlGenerator)
        {
            Action = "Privacy",
            ViewContext = viewContext,

        };
        var anchorOutput = new TagHelperOutput("a", new TagHelperAttributeList(),
            (useCachedResult, encoder) =>  Task.Factory.StartNew<TagHelperContent>(
                 () => new DefaultTagHelperContent()));
        anchorOutput.Content.AppendHtml("Privacy Link");
        var anchorContext = new TagHelperContext(
            new TagHelperAttributeList(new[]
            {
                new TagHelperAttribute("asp-action", new HtmlString("Privacy"))
            }),
                new Dictionary<object, object>(),
                Guid.NewGuid().ToString());

        anchorTagHelper.ProcessAsync(anchorContext, anchorOutput).GetAwaiter().GetResult();
        output.Content.SetHtmlContent(anchorOutput);
    }
}


来源:https://stackoverflow.com/questions/54582450/instantiating-and-invoking-taghelpers-manually

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!