在作为标记助手调用的视图组件中,我们如何访问内部HTML?

时间:2018-06-16 15:34:32

标签: asp.net-core asp.net-core-mvc tag-helpers asp.net-core-mvc-2.0 view-components

在标记助手中,我们可以访问标记内部HTML。

<!-- Index.cshtml -->  
<my-first>
    This is the original Inner HTML from the *.cshtml file.
</my-first>

// MyFirstTagHelper.cs > ProcessAsync
var childContent = await output.GetChildContentAsync();
var innerHtml = childContent.GetContent();

如果我们invoke a view component as a tag helper,我们如何访问内部HTML?

<vc:my-first>
    This is the original Inner HTML from the *.cshtml file.
</vc:my-first>

// MyFirstViewComponent.cs > InvokeAsync()
var innerHtml = DoMagic();

进一步的想法:

我很欣赏我们可以通过HTML属性将任意内容传递给视图组件。但是,在大量文本的情况下,这可能变得不切实际,在这种情况下,内部HTML将更具可读性并具有更好的工具支持。

有些人可能会说,“为什么不只是使用标签助手呢?”好吧,我们希望将视图与标记帮助器关联,标记帮助程序不支持视图;相反,标记助手要求我们以编程方式构建所有HTML。

所以我们陷入了一些束缚。一方面,我们需要一个标签帮助器,但它们不支持视图;另一方面,我们可以使用视图组件作为标记帮助器,但视图组件可能不允许我们访问内部HTML。

2 个答案:

答案 0 :(得分:1)

很抱歉,答案是&#34;只需使用代码帮助&#34;

请参阅以下问题:https://github.com/aspnet/Mvc/issues/5465

能够从标记帮助程序调用{​​{1}}只是一种不同的方式来调用它而不是使用ViewComponent

我可以看到这是误导性的,我记得在ASP.NET Core 2.1教程中看到一个关于&#34; View Components的效果的声明就像Tag Helpers,但更强大。&#34; < / p>

答案 1 :(得分:0)

最后,一种既可以吃蛋糕又可以吃的方法!允许标签助手使用 Razor 视图作为其 HTML 源,但在 Razor 页面中使用时仍然包装标记。

使用标签助手将内部 HTML 作为字符串获取。然后直接操作 Razor 视图引擎,将局部视图渲染为字符串。最后,使用字符串替换将内部 HTML 字符串放到局部视图字符串中的正确位置。

关键是使用可用于将 Razor 视图渲染为字符串的高质量 StackOverflow 答案。请参阅 IrazorViewToStringRenderer 服务 here(它说 ASP.NET Core 3.1 但在 2.2 中对我有用),或在其他地方作为 Mvc.RenderViewToString

标签助手:

// RazorViewTagHelper.cs
using Microsoft.AspNetCore.Razor.TagHelpers;

namespace GetSafetyCone.TagHelpers
{
    public class RazorViewTagHelper : TagHelper
    {
        private IRazorViewToStringRenderer RazorViewToStringRenderer { get; }
        
        public ViewName { get; set; }


        public RazorViewedTagHelperBase(
            IRazorViewToStringRenderer razorViewToStringRenderer)
        {
            this.RazorViewToStringRenderer = razorViewToStringRenderer;
        }

        public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
        {
            var childContent = await output.GetChildContentAsync();

            var childContentString = childContent.GetContent();
        
            var viewHtmlTemplateString = await this.RazorViewToStringRenderer.Render<object>(this.ViewName, null);
            
            var viewHtmlString = viewHtmlTemplateString.Replace("BODY_GOES_HERE", childContentString);

            output.Content.SetHtmlContent(viewHtmlString); // Set the content.
        }
    }
}

要用作标签助手的 HTML 源的部分视图:

// ViewXYZ.cshtml
@*
    ViewXYZ to be rendered to string.
*@
// No model specified, so ok model was a null object.
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
    <div class="max-w-3xl mx-auto">
        BODY_GOES_HERE
    </div>
</div>

这是正在使用的标签助手:

// YourPage.cshtml
<razor-view view-name="ViewXYZ">
    <p>You should see this content wrapped in the ViewXYZ divs.</p>
</razor-view>

如果需要,可以简化字符串替换,直接使用 childContent TagHelperContent 作为视图的模型:

// RazorViewTagHelper.cs
...
var childContent = await output.GetChildContentAsync();

var viewHtmlString = await this.RazorViewToStringRenderer.Render("viewName", childContent);
...

// ViewXYZ.cshtml
...
@model Microsoft.AspNetCore.Razor.TagHelpers.TagHelperContent;
...
<div class="max-w-3xl mx-auto">
    @(this.Model)
</div>
...