根据this article,如果我们使用多个标记帮助程序(针对相同的标记),并且在每个标记帮助程序中,我们将使用await output.GetChildContentAsync()
来接收html内容,我们将通过缓存输出来解决问题:
问题是标记帮助器输出是高速缓存的,当运行WWW标记助手时,它会覆盖HTTP标记助手的高速缓存输出。
使用如下语句修复问题:
var childContent = output.Content.IsModified ? output.Content.GetContent() :
(await output.GetChildContentAsync()).GetContent();
此行为的描述:
上面的代码检查内容是否已被修改,以及是否 它有,它从输出缓冲区获取内容。
问题是:
1)引擎盖下TagHelperOutput.GetChildContentAsync()
和TagHelperOutput.Content.GetContent()
之间有什么区别?
2)哪种方法将结果写入缓冲区?
3)它是什么意思"缓存输出":ASP.NET MVC Core缓存TagHelper
调用后的初始剃刀标记或html标记?
提前感谢!
答案 0 :(得分:1)
经过一些源代码分析后,我得到了答案:
区别在于:
- 方法TagHelperOutput.GetChildContentAsync()
执行子TagHelpers
并将结果生成为TagHelperContent
。从这个对象我们可以接收html标记作为调用内部TagHelpers的结果,并进一步使用它作为当前TagHelper结果。此方法还缓存呈现内部TagHelperContents的子Tasks
。
在同一元素的范围内调用此方法将产生相同的结果(来自缓存)。
- 方法TagHelperOutput.Content.GetContent()
从调用TagHelperOutput.GetChildContentAsync()
的缓冲结果中返回html标记。这意味着,如果我们未在第一个TagHelper中调用TagHelperOutput.GetChildContentAsync()
方法,则会收到string.Empty
结果。
代码示例:
1)此助手将产生string.Empty
结果,因为TagHelperOutput.GetChildContentAsync()
未被调用:
[HtmlTargetElement("p")]
public class AutoLinkerHttpTagHelper : TagHelper
{
public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
{
var childContent = output.Content.GetContent();
output.Content.SetHtmlContent(Regex.Replace(
childContent,
@"\b(?:https?://)(\S+)\b",
"<a target=\"_blank\" href=\"$0\">$0</a>"
));
}
}
[HtmlTargetElement("p")]
public class AutoLinkerWwwTagHelper : TagHelper
{
public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
{
var childContentBySync = output.Content.GetContent();
output.Content.SetHtmlContent(Regex.Replace(
childContentBySync,
@"\b(www\.)(\S+)\b",
"<a target=\"_blank\" href=\"http://$0\">$0</a>"));
}
}
2)如果我们改变第一个帮助器的ProcessAsync
方法,那么:
public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
{
var childContent = (await output.GetChildContentAsync()).GetContent();
output.Content.SetHtmlContent(Regex.Replace(
childContent,
@"\b(?:https?://)(\S+)\b",
"<a target=\"_blank\" href=\"$0\">$0</a>"
));
}
结果没问题。
这是输出结果的一些保险:
var childContent = output.Content.IsModified ? output.Content.GetContent() :
(await output.GetChildContentAsync()).GetContent();
换句话说,我们检查是否调用了GetChildContentAsync()
。
希望它会对某人有所帮助。
答案 1 :(得分:0)
其他答案的解释对我来说还不清楚,因此我对其进行了测试,以下是摘要:
await output.GetChildContentAsync();
=>获取标记内的原始内容,该内容在Razor文件中进行了硬编码。请注意,它将在第一次调用时被缓存,并且在以后的调用中永远不会更改,因此它不会反映其他TagHelpers在运行时所做的更改!
output.Content.GetContent();
=>仅应用于获取由某些TagHelper修改的内容,否则将返回Empty!
用法样本:
获取最新内容(无论是初始剃刀还是其他标签助手修改的内容):
var curContent = output.IsContentModified ? output.Content : await output.GetChildContentAsync();
string strContent = curContent.GetContent();