diff --git a/src/Microsoft.AspNetCore.Razor.Runtime/Runtime/TagHelpers/TagHelperExecutionContext.cs b/src/Microsoft.AspNetCore.Razor.Runtime/Runtime/TagHelpers/TagHelperExecutionContext.cs
index 8923a8bfaa..aa826dbbd5 100644
--- a/src/Microsoft.AspNetCore.Razor.Runtime/Runtime/TagHelpers/TagHelperExecutionContext.cs
+++ b/src/Microsoft.AspNetCore.Razor.Runtime/Runtime/TagHelpers/TagHelperExecutionContext.cs
@@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Text.Encodings.Web;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Razor.TagHelpers;
@@ -243,6 +244,28 @@ namespace Microsoft.AspNetCore.Razor.Runtime.TagHelpers
Output.Reinitialize(tagName, tagMode);
}
+ ///
+ /// Executes children asynchronously with the page's in scope and
+ /// sets 's to the rendered results.
+ ///
+ /// A that on completion sets 's
+ /// to the children's rendered content.
+ public async Task SetOutputContentAsync()
+ {
+ var childContent = _childContent;
+
+ if (childContent == null)
+ {
+ _startTagHelperWritingScope(null);
+ await _executeChildContentAsync();
+ childContent = _endTagHelperWritingScope();
+ }
+
+ Debug.Assert(!Output.IsContentModified);
+
+ Output.Content.SetHtmlContent(childContent);
+ }
+
// Internal for testing.
internal async Task GetChildContentAsync(bool useCachedResult, HtmlEncoder encoder)
{
diff --git a/src/Microsoft.AspNetCore.Razor/CodeGenerators/CSharpTagHelperCodeRenderer.cs b/src/Microsoft.AspNetCore.Razor/CodeGenerators/CSharpTagHelperCodeRenderer.cs
index 132915b4f3..f93acf499f 100644
--- a/src/Microsoft.AspNetCore.Razor/CodeGenerators/CSharpTagHelperCodeRenderer.cs
+++ b/src/Microsoft.AspNetCore.Razor/CodeGenerators/CSharpTagHelperCodeRenderer.cs
@@ -583,13 +583,10 @@ namespace Microsoft.AspNetCore.Razor.CodeGenerators
using (_writer.BuildScope())
{
_writer
- .Write(tagHelperOutputAccessor)
- .Write(".")
- .WriteStartAssignment(_tagHelperContext.TagHelperOutputContentPropertyName)
.Write("await ")
.WriteInstanceMethodInvocation(
- tagHelperOutputAccessor,
- _tagHelperContext.TagHelperOutputGetChildContentAsyncMethodName);
+ ExecutionContextVariableName,
+ _tagHelperContext.ExecutionContextSetOutputContentAsyncMethodName);
}
}
diff --git a/src/Microsoft.AspNetCore.Razor/CodeGenerators/GeneratedTagHelperContext.cs b/src/Microsoft.AspNetCore.Razor/CodeGenerators/GeneratedTagHelperContext.cs
index 5af4cebe16..e7db286a03 100644
--- a/src/Microsoft.AspNetCore.Razor/CodeGenerators/GeneratedTagHelperContext.cs
+++ b/src/Microsoft.AspNetCore.Razor/CodeGenerators/GeneratedTagHelperContext.cs
@@ -37,7 +37,7 @@ namespace Microsoft.AspNetCore.Razor.CodeGenerators
HtmlEncoderPropertyName = "HtmlEncoder";
TagHelperOutputIsContentModifiedPropertyName = "IsContentModified";
TagHelperOutputContentPropertyName = "Content";
- TagHelperOutputGetChildContentAsyncMethodName = "GetChildContentAsync";
+ ExecutionContextSetOutputContentAsyncMethodName = "SetOutputContentAsync";
TagHelperAttributeTypeName = "Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute";
EncodedHtmlStringTypeName = "Microsoft.AspNetCore.Html.HtmlEncodedString";
}
@@ -209,10 +209,10 @@ namespace Microsoft.AspNetCore.Razor.CodeGenerators
public string TagHelperOutputContentPropertyName { get; set; }
///
- /// The name of the method on the property used to retrieve
- /// tag helper child content.
+ /// The name of the method on the property used to execute
+ /// child content and set the rendered results on its property.
///
- public string TagHelperOutputGetChildContentAsyncMethodName { get; set; }
+ public string ExecutionContextSetOutputContentAsyncMethodName { get; set; }
///
/// The name of the type used to represent tag helper attributes.
diff --git a/test/Microsoft.AspNetCore.Razor.Runtime.Test/Runtime/TagHelpers/TagHelperExecutionContextTest.cs b/test/Microsoft.AspNetCore.Razor.Runtime.Test/Runtime/TagHelpers/TagHelperExecutionContextTest.cs
index e6e0103b65..d246b3556b 100644
--- a/test/Microsoft.AspNetCore.Razor.Runtime.Test/Runtime/TagHelpers/TagHelperExecutionContextTest.cs
+++ b/test/Microsoft.AspNetCore.Razor.Runtime.Test/Runtime/TagHelpers/TagHelperExecutionContextTest.cs
@@ -14,6 +14,33 @@ namespace Microsoft.AspNetCore.Razor.Runtime.TagHelpers
{
public class TagHelperExecutionContextTest
{
+ [Fact]
+ public async Task SetOutputContentAsync_SetsOutputsContent()
+ {
+ // Arrange
+ var tagHelperContent = new DefaultTagHelperContent();
+ var content = "Hello from child content";
+ var executionContext = new TagHelperExecutionContext(
+ "p",
+ tagMode: TagMode.StartTagAndEndTag,
+ items: new Dictionary