diff --git a/src/Mvc/Mvc.ViewFeatures/src/Buffers/ViewBuffer.cs b/src/Mvc/Mvc.ViewFeatures/src/Buffers/ViewBuffer.cs
index e1c738220cc6..089dd0323104 100644
--- a/src/Mvc/Mvc.ViewFeatures/src/Buffers/ViewBuffer.cs
+++ b/src/Mvc/Mvc.ViewFeatures/src/Buffers/ViewBuffer.cs
@@ -12,7 +12,7 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures.Buffers;
/// An that is backed by a buffer provided by .
///
[DebuggerDisplay("{DebuggerToString()}")]
-internal class ViewBuffer : IHtmlContentBuilder
+internal sealed class ViewBuffer : IHtmlContentBuilder
{
public const int PartialViewPageSize = 32;
public const int TagHelperPageSize = 32;
diff --git a/src/Mvc/Mvc.ViewFeatures/src/RazorComponents/HtmlRenderer.cs b/src/Mvc/Mvc.ViewFeatures/src/RazorComponents/HtmlRenderer.cs
index 2fa943a3497a..b2213734514c 100644
--- a/src/Mvc/Mvc.ViewFeatures/src/RazorComponents/HtmlRenderer.cs
+++ b/src/Mvc/Mvc.ViewFeatures/src/RazorComponents/HtmlRenderer.cs
@@ -3,7 +3,9 @@
using System.Diagnostics;
using System.Runtime.ExceptionServices;
+using System.Text.Encodings.Web;
using Microsoft.AspNetCore.Components.RenderTree;
+using Microsoft.AspNetCore.Html;
using Microsoft.AspNetCore.Mvc.ViewFeatures.Buffers;
using Microsoft.Extensions.Logging;
@@ -47,14 +49,11 @@ protected override Task UpdateDisplayAsync(in RenderBatch renderBatch)
public async Task RenderComponentAsync(Type componentType, ParameterView initialParameters)
{
- var (componentId, frames) = await CreateInitialRenderAsync(componentType, initialParameters);
-
- var viewBuffer = new ViewBuffer(_viewBufferScope, nameof(HtmlRenderer), ViewBuffer.ViewPageSize);
+ var component = InstantiateComponent(componentType);
+ var componentId = AssignRootComponentId(component);
- var context = new HtmlRenderingContext { HtmlContentBuilder = viewBuffer, };
- var newPosition = RenderFrames(context, frames, 0, frames.Count);
- Debug.Assert(newPosition == frames.Count);
- return new ComponentRenderedText(componentId, context.HtmlContentBuilder);
+ await RenderRootComponentAsync(componentId, initialParameters);
+ return new ComponentRenderedText(componentId, new ComponentHtmlContent(this, componentId));
}
public Task RenderComponentAsync(ParameterView initialParameters) where TComponent : IComponent
@@ -248,21 +247,50 @@ private static int RenderAttributes(
return position + maxElements;
}
- private async Task<(int, ArrayRange)> CreateInitialRenderAsync(Type componentType, ParameterView initialParameters)
+ private ViewBuffer GetRenderedHtmlContent(int componentId)
{
- var component = InstantiateComponent(componentType);
- var componentId = AssignRootComponentId(component);
+ var viewBuffer = new ViewBuffer(_viewBufferScope, nameof(HtmlRenderer), ViewBuffer.ViewPageSize);
+ var context = new HtmlRenderingContext(viewBuffer);
- await RenderRootComponentAsync(componentId, initialParameters);
+ var frames = GetCurrentRenderTreeFrames(componentId);
+ var newPosition = RenderFrames(context, frames, 0, frames.Count);
+ Debug.Assert(newPosition == frames.Count);
- return (componentId, GetCurrentRenderTreeFrames(componentId));
+ return viewBuffer;
}
private sealed class HtmlRenderingContext
{
- public ViewBuffer HtmlContentBuilder { get; init; }
+ public HtmlRenderingContext(ViewBuffer viewBuffer)
+ {
+ HtmlContentBuilder = viewBuffer;
+ }
+
+ public ViewBuffer HtmlContentBuilder { get; }
public string ClosestSelectValueAsString { get; set; }
}
+
+ ///
+ /// A that defers rendering component markup until
+ /// is called.
+ ///
+ private sealed class ComponentHtmlContent : IHtmlContent
+ {
+ private readonly HtmlRenderer _renderer;
+ private readonly int _componentId;
+
+ public ComponentHtmlContent(HtmlRenderer renderer, int componentId)
+ {
+ _renderer = renderer;
+ _componentId = componentId;
+ }
+
+ public void WriteTo(TextWriter writer, HtmlEncoder encoder)
+ {
+ var actualHtmlContent = _renderer.GetRenderedHtmlContent(_componentId);
+ actualHtmlContent.WriteTo(writer, encoder);
+ }
+ }
}
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/Pages/_Host.cshtml b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/Pages/_Host.cshtml
index c8b0009bc2a2..132aad8a77a4 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/Pages/_Host.cshtml
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/Pages/_Host.cshtml
@@ -1,8 +1,33 @@
@page "/"
+@using Microsoft.AspNetCore.Components.Web
@namespace BlazorServerWeb_CSharp.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
-@{
- Layout = "_Layout";
-}
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ An error has occurred. This application may no longer respond until reloaded.
+
+
+ An unhandled exception has occurred. See browser dev tools for details.
+
+ Reload
+ 🗙
+
-
- An error has occurred. This application may no longer respond until reloaded.
-
-
- An unhandled exception has occurred. See browser dev tools for details.
-
- Reload
- 🗙
-