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

Asp.net core 在作为标记助手调用的视图组件中,我们如何访问内部HTML?,asp.net-core,asp.net-core-mvc,tag-helpers,asp.net-core-mvc-2.0,view-components,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(); va

在标记帮助程序中,我们可以访问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();

这是*.cshtml文件中的原始内部HTML。
//MyFirstTagHelper.cs>ProcessAsync
var childContent=await output.GetChildContentAsync();
var innerHtml=childContent.GetContent();
如果是,我们如何访问内部HTML

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

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

这是*.cshtml文件中的原始内部HTML。
//MyFirstViewComponent.cs>InvokeAsync()
var innerHtml=DoMagic();
还有一些想法:

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

有些人可能会说,“那么为什么不使用标记辅助对象呢?”好吧,我们想将视图与标记辅助对象关联,而标记辅助对象不支持视图;相反,标记帮助程序要求我们以编程方式构建所有HTML

所以我们陷入了困境。一方面,我们需要一个标记助手,但它们不支持视图;另一方面,我们可以使用视图组件作为标记助手,但是视图组件可能不允许我们访问内部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();
见以下问题:

能够从标记帮助器调用
ViewComponent
只是调用它的另一种方式,而不是使用
@Component.invoke()


我可以看出这是一种误导,我确实记得在ASP.NET Core 2.1教程中看到过一句话,大意是“视图组件类似于标记助手,但功能更强大。”

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

使用标记帮助器以字符串形式获取内部HTML。然后直接操作Razor视图引擎,将局部视图渲染为字符串。最后,使用字符串替换将内部HTML字符串放置在部分视图字符串的正确位置

关键是在将Razor视图渲染为字符串时使用高质量的StackOverflow答案。请参阅IRazorViewToStringRenderer服务(上面说的是ASP.NET Core 3.1,但在2.2中对我有用),或者其他类似的服务

标记帮助器:

// 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.
        }
    }
}
// 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>
//RazorViewTagHelper.cs
使用Microsoft.AspNetCore.Razor.TagHelpers;
命名空间GetSafetyCone.TagHelpers
{
公共类RazorViewTagHelper:TagHelper
{
私有IRazorViewToStringRenderer RazorViewToStringRenderer{get;}
公共视图名{get;set;}
公共RazorViewedTagHelperBase(
IRazorViewToStringRenderer(razorViewToStringRenderer)
{
this.razorViewToStringRender=RazorViewToStringRender;
}
公共重写异步任务ProcessAsync(TagHelperContext上下文,TagHelperOutput输出)
{
var childContent=await output.GetChildContentAsync();
var childContentString=childContent.GetContent();
var viewHtmlTemplateString=等待this.razorViewToStringRender.Render(this.ViewName,null);
var viewHtmlString=viewHtmlTemplateString.Replace(“BODY\u GOES\u HERE”,childContentString);
output.Content.SetHtmlContent(viewHtmlString);//设置内容。
}
}
}
要用作标记帮助器HTML源的局部视图:

// 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.
        }
    }
}
// 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>
//ViewXYZ.cshtml
@*
要渲染为字符串的ViewXYZ。
*@
//没有指定模型,所以ok模型是空对象。
身体在这里
下面是正在使用的标记帮助器:

// YourPage.cshtml
<razor-view view-name="ViewXYZ">
    <p>You should see this content wrapped in the ViewXYZ divs.</p>
</razor-view>
//YourPage.cshtml
您应该可以在ViewXYZ divs中看到此内容

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

// 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>
...
//RazorViewTagHelper.cs
...
var childContent=await output.GetChildContentAsync();
var viewHtmlString=wait this.razorviewtostringrender.Render(“viewName”,childContent);
...
//ViewXYZ.cshtml
...
@型号:Microsoft.AspNetCore.Razor.TagHelpers.TagHelperContent;
...
@(该模型)
...

对我来说,关键是我们不能既有蛋糕又吃蛋糕。如果我们使用标记辅助对象,那么我们就不能拥有razor视图。如果使用视图组件,则无法访问内部HTML。Bummer.综上所述,我认为关于您的问题的下一个问题是,为什么您需要访问视图组件的内部html?是否有其他方法处理内部html所需的内容并将其发送到视图组件,可能是
ViewComponent.Content(string)
方法?这对我来说是非常新的东西。我需要访问内部HTML,因为我正在构建一个代码示例标记。理想情况下,它看起来像这样:
var foo=“bar”。我知道没有其他方法可以处理代码块并将其发送到视图组件。我们可以简单地将代码样本作为另一个参数传递,但是使用大型代码样本读取标记会变得更加困难。我也这么想。您是否考虑过合并其中一个Javascript框架的可能性?ReactJS/KnockoutJS/VueJS/AngularJS(非角度)可能适合此用例