gpt4 book ai didi

c# - 添加简单的 TagHelper 会导致此错误 : "RenderBody has not been called for the page "

转载 作者:行者123 更新时间:2023-12-02 03:05:34 27 4
gpt4 key购买 nike

Code available here

在 ASP.NET Core 3.0 Web 应用程序中,我添加了以下简单的标记帮助器:

[HtmlTargetElement("submit-button")]
public class SubmitButtonTagHelper : TagHelper
{
public string Title { get; set; } = "Submit";
public string Classes { get; set; }
public string Id { get; set; }

public override void Process(TagHelperContext context, TagHelperOutput output)
{
output.Content.SetHtmlContent(
$@"<span class=""btn btn-primary {Classes}"" id=""{Id}"">{Title}</span>");
}
}

我打算这样使用:

<submit-button></submit-button>

但是,添加 SubmitButtonTagHelper 而不尝试使用它的行为会导致以下运行时异常:

InvalidOperationException: RenderBody has not been called for the page at '/Views/Shared/_Layout.cshtml'. To ignore call IgnoreBody().

我通过将此行添加到 Pages/_ViewImports.cshtml 文件中来导入标签助手:

@addTagHelper *, Web

我的 _Layout.cshtml 页面如下所示:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title><vc:product-name></vc:product-name> @ViewData["Title"]</title>

@RenderSection("Styles", required: false)

<partial name="_FrameworkStyles" />
</head>
<body class="top-navigation">

<div id="wrapper">
<div id="page-wrapper" class="gray-bg">
<div class="">
<vc:Navigation></vc:Navigation>

@RenderBody()

<div class="footer"></div>
</div>
</div>
</div>


<partial name="_FrameworkScripts" />

@RenderSection("Scripts", required: false)
</body>
</html>

我这里怎么出错了?在调试时,我可以看到 SubmitButtonTagHelper 中遇到了断点,但我还没有在任何地方引用它?据我了解, [HtmlTargetElement] 属性意味着它仅适用于元素标记为“提交按钮”的地方。这不正确吗?

我的项目中还有另一个标签助手,我还注意到该类中的断点也在我没有引用它的地方被命中。

我确实做了一些愚蠢的事情,但是什么?

最佳答案

ASP.NET Core MVC 有 Tag Helper Components 的概念:

A Tag Helper Component is a Tag Helper that allows you to conditionally modify or add HTML elements from server-side code.

...

Tag Helper Components don't require registration with the app in _ViewImports.cshtml.

...

Two common use cases of Tag Helper Components include:

  1. Injecting a <link> into the <head>.
  2. Injecting a <script> into the <body>.

同样来自文档,这里是标签帮助器组件的实现:

public class AddressStyleTagHelperComponent : TagHelperComponent
{
private readonly string _style =
@"<link rel=""stylesheet"" href=""/css/address.css"" />";

public override int Order => 1;

public override Task ProcessAsync(TagHelperContext context,
TagHelperOutput output)
{
if (string.Equals(context.TagName, "head",
StringComparison.OrdinalIgnoreCase))
{
output.PostContent.AppendHtml(_style);
}

return Task.CompletedTask;
}
}

注册后(如下所示),AddressStyleTagHelperComponent将运行两次:一次为 head元素;一次为body元素。下面是它向 DI 注册的方式:

services.AddTransient<ITagHelperComponent, AddressScriptTagHelperComponent>();

此时(或者甚至更早),您可能认为我疯了。这与 SubmitButtonTagHelper 有什么关系? ?

通过其继承树,SubmitButtonTagHelper最终实现 ITagHelperComponent 。如果您要添加以下 DI 注册,SubmitButtonTagHelper将作为标签帮助器组件运行一次 head一次 body :

services.AddTransient<ITagHelperComponent, SubmitButtonTagHelper>();

SubmitButtonTagHelper具有破坏性,会替换其操作的元素的全部内容。如果要替换body的内容元素, body 当然会失去它的RenderBody指令。

所以,这是对如果 SubmitButtonTagHelper 可能发生的情况的详细解释。已注册为标签帮助器组件。毫不奇怪,这正是您上传到 GitHub ( source ) 的示例中所发生的情况:

private static void WebRegistration(ContainerBuilder builder)
{
builder.RegisterAutowiredAssemblyInterfaces(Assembly.Load(Web));
builder.RegisterAutowiredAssemblyTypes(Assembly.Load(Web));
}

我对Autofac了解不多,但是很明显,对RegisterAutowiredAssemblyInterfaces的调用如上所示找到 SubmitButtonTagHelper并将其注册到其所有接口(interface),包括 ITagHelperComponent .

同样,我对 Autofac 了解不多,但最终,不打算作为标记帮助程序组件运行的标记帮助程序应该被排除在此自动注册过程之外。以下是关于如何进行此过滤的建议,尽管我认为这是一种糟糕的 Autofac 方法:

builder.RegisterAutowiredAssemblyInterfaces(Assembly.Load(Web))
.Where(x => !x.Name.EndsWith("TagHelper"));

关于c# - 添加简单的 TagHelper 会导致此错误 : "RenderBody has not been called for the page ",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59918819/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com