手动实例化和调用TagHelpers

时间:2019-02-07 21:18:53

标签: c# razor asp.net-core dependency-injection asp.net-core-tag-helpers

这是this question的后续问题,它似乎是针对较旧的ASP.NET Core版本(我使用的是2.1)。

我正在尝试从TagHelper内部手动调用TagHelper。在上面的链接问题中应用答案,TagHelper.Process如下所示:

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

此时会发生几个编译器错误。

  

无法从'System.Guid'转换为'string'

没问题,我可以转换为字符串。

  

没有给出与所需形式相对应的参数   HtmlString.HtmlString(string)

的参数“ value”

在MSDN页面上检查TagHelperOutput constructor,看来它不再需要HtmlString

我将该参数更改为委托函数:

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

最后一个编译器错误:

  

没有给出与所需形式相对应的参数   的参数“发电机”   'AnchorTagHelper.AnchorTagHelper(IHtmlGenerator)

希望它是一个可选参数,我传入了null:

var anchorTagHelper = new AnchorTagHelper(null);

最终编译完成-但这导致运行时出现空指针异常:

  

Microsoft.AspNetCore.Mvc.TagHelpers.InputTagHelper.Process(TagHelperContext   上下文,TagHelperOutput输出)

因此,我的问题是:如何实例化AnchorTagHelper,以便可以在C#中手动调用TagHelpers?

编辑:我已经将IHtmlGenerator DI了,并得到了更有意义的错误消息:

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

值不能为null。参数名称:viewContext>

     

Microsoft.AspNetCore.Mvc.ViewFeatures.DefaultHtmlGenerator.GenerateActionLink(ViewContext   viewContext,字符串linkText,字符串actionName,字符串   controllerName,字符串协议,字符串主机名,字符串片段,   对象routeValues,对象htmlAttributes)位于   Microsoft.AspNetCore.Mvc.TagHelpers.AnchorTagHelper.Process(TagHelperContext   上下文,TagHelperOutput输出)位于   EAGLEweb2020.Models.EAGLEinputTagHelper.Process(TagHelperContext   上下文,TagHelperOutput输出)   C:\ Users \ 1135937 \ source \ repos \ EAGLEweb2020 \ EAGLEweb2020 \ Models \ TagHelpers \ EAGLEinputTagHelper.cs:line   66岁   Microsoft.AspNetCore.Razor.TagHelpers.TagHelper.ProcessAsync(TagHelperContext   上下文,TagHelperOutput输出)位于   Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner.d__0.MoveNext()

但是我如何DI ViewContext?

编辑2:

结果证明ViewContext是AnchorTagHelper中的公共属性:

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

但是现在内容为空...

1 个答案:

答案 0 :(得分:1)

嗨,我正在经历这个过程,您陷入了ViewContext和Output的困境。 我做了一个类似的项目。这是代码,希望对您有所帮助。

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