是否可以从自定义TagHelper调用ViewComponent?

时间:2017-07-04 19:57:34

标签: c# asp.net-core asp.net-core-tag-helpers asp.net-core-viewcomponent

我正在编写自定义TagHelper并希望在其中呈现ViewComponent。 类似于vc:xyz标签帮助器的东西,但是以更加可控的方式,这样我就可以在运行时确定要渲染哪个ViewComponent。

有可能吗?

2 个答案:

答案 0 :(得分:3)

为了做到这一点,您需要将IViewComponentHelper注入TagHelper,对其进行上下文化,然后根据您的应用程序逻辑使用它来呈现任何ViewComponent。这是一个快速说明:

[HtmlTargetElement("widget", Attributes = WidgetNameAttributeName)]
public class WidgetTagHelper : TagHelper
{
    private const string WidgetNameAttributeName = "name";
    private readonly IViewComponentHelper _viewComponentHelper;

    public WidgetTagHelper(IViewComponentHelper viewComponentHelper)
    {
        _viewComponentHelper = viewComponentHelper;
    }

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

    [HtmlAttributeName(WidgetNameAttributeName)]
    public string Name { get; set; }

    public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
    {
        ((IViewContextAware)_viewComponentHelper).Contextualize(ViewContext);

        var content = await _viewComponentHelper.InvokeAsync(typeof(WidgetViewComponent), new { name = Name });
        output.Content.SetHtmlContent(content);
    }
}

另外,请记住,自动关闭标签不起作用:

<widget name="abc" />

请改用此表格:

<widget name="abc"></widget>

答案 1 :(得分:0)

跟进answer

调用标记帮助程序时无需编写结束标记。只需在ProcessAsync中设置TagMode

output.TagMode = TagMode.StartTagAndEndTag;
output.Content.SetHtmlContent(content);

然后<widget name="abc" />完全正常。

或者,您可以在不渲染标记本身的情况下呈现视图组件的内容来代替widget标记:

output.SuppressOutput();
output.PostElement.SetHtmlContent(content);

我还注意到在视图组件的view中添加自闭标签会使它们在最终结果中显示错误,但这可能是一个不同的主题。