Skip to content

Commit a19f86e

Browse files
Add Results.Extensions extension helpers for returning the RazorComponentResult.
1 parent e919cd8 commit a19f86e

5 files changed

+63
-4
lines changed

src/Mvc/Mvc.ViewFeatures/src/Microsoft.AspNetCore.Mvc.ViewFeatures.csproj

+1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
<Reference Include="Microsoft.AspNetCore.Antiforgery" />
2626
<Reference Include="Microsoft.AspNetCore.Diagnostics.Abstractions" />
2727
<Reference Include="Microsoft.AspNetCore.Html.Abstractions" />
28+
<Reference Include="Microsoft.AspNetCore.Http.Results" />
2829
<Reference Include="Microsoft.Extensions.WebEncoders" />
2930
<Reference Include="Microsoft.AspNetCore.Components.Authorization" />
3031
<Reference Include="Microsoft.AspNetCore.Components.Web" />

src/Mvc/Mvc.ViewFeatures/src/PublicAPI.Unshipped.txt

+4
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ Microsoft.AspNetCore.Mvc.Diagnostics.BeforeRazorComponentEventData
55
Microsoft.AspNetCore.Mvc.Diagnostics.BeforeRazorComponentEventData.RenderMode.get -> Microsoft.AspNetCore.Mvc.Rendering.RenderMode
66
Microsoft.AspNetCore.Mvc.Rendering.FormMethod.Dialog = 2 -> Microsoft.AspNetCore.Mvc.Rendering.FormMethod
77
Microsoft.AspNetCore.Mvc.ViewFeatures.RazorComponentResult
8+
Microsoft.AspNetCore.Mvc.ViewFeatures.RazorComponentResultExtensions
89
~Microsoft.AspNetCore.Mvc.ViewFeatures.RazorComponentResult.Parameters.get -> object
910
~Microsoft.AspNetCore.Mvc.ViewFeatures.RazorComponentResult.Parameters.set -> void
1011
Microsoft.AspNetCore.Mvc.ViewFeatures.RazorComponentResult.RenderMode.get -> Microsoft.AspNetCore.Mvc.Rendering.RenderMode
@@ -29,6 +30,9 @@ Microsoft.Extensions.DependencyInjection.RazorComponentsServiceCollectionExtensi
2930
~Microsoft.AspNetCore.Mvc.ViewFeatures.RazorComponentResultExecutor.RazorComponentResultExecutor(Microsoft.AspNetCore.Mvc.Infrastructure.IHttpResponseStreamWriterFactory writerFactory, System.Diagnostics.DiagnosticListener diagnosticListener) -> void
3031
~Microsoft.AspNetCore.Mvc.ViewFeatures.RazorComponentResultExecutor.WriterFactory.get -> Microsoft.AspNetCore.Mvc.Infrastructure.IHttpResponseStreamWriterFactory
3132
~override Microsoft.AspNetCore.Mvc.ViewFeatures.RazorComponentResult.ExecuteResultAsync(Microsoft.AspNetCore.Mvc.ActionContext context) -> System.Threading.Tasks.Task
33+
~static Microsoft.AspNetCore.Mvc.ViewFeatures.RazorComponentResultExtensions.RazorComponent<TComponent>(this Microsoft.AspNetCore.Http.IResultExtensions resultExtensions) -> Microsoft.AspNetCore.Mvc.IActionResult
34+
~static Microsoft.AspNetCore.Mvc.ViewFeatures.RazorComponentResultExtensions.RazorComponent<TComponent>(this Microsoft.AspNetCore.Http.IResultExtensions resultExtensions, Microsoft.AspNetCore.Mvc.Rendering.RenderMode renderMode, object componentParameters) -> Microsoft.AspNetCore.Mvc.IActionResult
35+
~static Microsoft.AspNetCore.Mvc.ViewFeatures.RazorComponentResultExtensions.RazorComponent<TComponent>(this Microsoft.AspNetCore.Http.IResultExtensions resultExtensions, object componentParameters) -> Microsoft.AspNetCore.Mvc.IActionResult
3236
~static Microsoft.Extensions.DependencyInjection.RazorComponentsServiceCollectionExtensions.AddRazorComponents(this Microsoft.Extensions.DependencyInjection.IServiceCollection services) -> void
3337
~static readonly Microsoft.AspNetCore.Mvc.ViewFeatures.RazorComponentResultExecutor.DefaultContentType -> string
3438
~virtual Microsoft.AspNetCore.Mvc.ViewFeatures.RazorComponentResultExecutor.ExecuteAsync(Microsoft.AspNetCore.Mvc.ActionContext actionContext, Microsoft.AspNetCore.Mvc.ViewFeatures.RazorComponentResult result) -> System.Threading.Tasks.Task

src/Mvc/Mvc.ViewFeatures/src/RazorComponents/RazorComponentResultExecutor.cs

+5-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using Microsoft.AspNetCore.Internal;
88
using Microsoft.AspNetCore.Mvc.Formatters;
99
using Microsoft.AspNetCore.Mvc.Infrastructure;
10+
using Microsoft.AspNetCore.Mvc.Rendering;
1011
using Microsoft.Extensions.DependencyInjection;
1112

1213
namespace Microsoft.AspNetCore.Mvc.ViewFeatures;
@@ -93,10 +94,13 @@ private static Task RenderComponentToResponse(ActionContext actionContext, Razor
9394
{ nameof(RazorComponentResultHost.RazorComponentResult), result },
9495
});
9596

97+
// Note that we always use Static rendering mode for the top-level output from a RazorComponentResult,
98+
// because you never want to serialize the invocation of RazorComponentResultHost. Instead, that host
99+
// component takes care of switching into your desired render mode when it produces its own output.
96100
var htmlContent = await componentPrerenderer.PrerenderComponentAsync(
97101
actionContext,
98102
typeof(RazorComponentResultHost),
99-
result.RenderMode,
103+
RenderMode.Static,
100104
hostParameters);
101105
await htmlContent.WriteToAsync(writer);
102106
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using Microsoft.AspNetCore.Components;
5+
using Microsoft.AspNetCore.Http;
6+
using Microsoft.AspNetCore.Mvc.Rendering;
7+
8+
namespace Microsoft.AspNetCore.Mvc.ViewFeatures;
9+
10+
/// <summary>
11+
/// Holds extension methods on <see cref="IResultExtensions"/>.
12+
/// </summary>
13+
public static class RazorComponentResultExtensions
14+
{
15+
/// <summary>
16+
/// Returns an <see cref="IActionResult"/> that renders a Razor Component.
17+
/// </summary>
18+
/// <typeparam name="TComponent">The type of component to render.</typeparam>
19+
/// <param name="resultExtensions">The <see cref="ResultExtensions"/>.</param>
20+
/// <returns>An <see cref="IActionResult"/> that renders a Razor Component.</returns>
21+
public static IActionResult RazorComponent<TComponent>(this IResultExtensions resultExtensions) where TComponent : IComponent
22+
=> new RazorComponentResult(typeof(TComponent));
23+
24+
/// <summary>
25+
/// Returns an <see cref="IActionResult"/> that renders a Razor Component.
26+
/// </summary>
27+
/// <typeparam name="TComponent">The type of component to render.</typeparam>
28+
/// <param name="resultExtensions">The <see cref="ResultExtensions"/>.</param>
29+
/// <param name="componentParameters">Parameters for the component.</param>
30+
/// <returns>An <see cref="IActionResult"/> that renders a Razor Component.</returns>
31+
public static IActionResult RazorComponent<TComponent>(this IResultExtensions resultExtensions, object componentParameters) where TComponent : IComponent
32+
=> new RazorComponentResult(typeof(TComponent)) { Parameters = componentParameters };
33+
34+
/// <summary>
35+
/// Returns an <see cref="IActionResult"/> that renders a Razor Component.
36+
/// </summary>
37+
/// <typeparam name="TComponent">The type of component to render.</typeparam>
38+
/// <param name="resultExtensions">The <see cref="ResultExtensions"/>.</param>
39+
/// <param name="componentParameters">Parameters for the component.</param>
40+
/// <param name="renderMode">A <see cref="RenderMode"/> value that specifies how to render the component.</param>
41+
/// <returns>An <see cref="IActionResult"/> that renders a Razor Component.</returns>
42+
public static IActionResult RazorComponent<TComponent>(this IResultExtensions resultExtensions, RenderMode renderMode, object componentParameters) where TComponent: IComponent
43+
=> new RazorComponentResult(typeof(TComponent)) { RenderMode = renderMode, Parameters = componentParameters };
44+
}

src/Mvc/Mvc.ViewFeatures/src/RazorComponents/RazorComponentResultHost.cs

+9-3
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,15 @@ private void BuildRenderTree(RenderTreeBuilder builder)
6161

6262
private void RenderPageWithParameters(RenderTreeBuilder builder)
6363
{
64-
// If we wanted to support rendering pre-instantiated component objects, it would probably go here
65-
// as either a whole new RenderTreeFrame type or as some mechanism to attach the instance onto a
66-
// regular Component frame (perhaps using a dummy ComponentState that represents 'not yet initialized')
64+
// TODO: Once we support rendering Server/WebAssembly components into the page, implementation will
65+
// go here. We need to switch into the rendermode given by RazorComponentResult.RenderMode for this
66+
// child component. That will cause the developer-supplied parameters to be serialized into a marker
67+
// but not attempt to serialize the RenderFragment that causes this to be hosted in its layout.
68+
69+
// TODO: If we wanted to support rendering pre-instantiated component objects, it would probably go here
70+
// as either a whole new RenderTreeFrame type or as some mechanism to attach the instance onto a regular
71+
// Component frame (perhaps using a dummy ComponentState that represents 'not yet initialized')
72+
6773
builder.OpenComponent(0, RazorComponentResult.ComponentType);
6874

6975
if (RazorComponentResult.Parameters is not null)

0 commit comments

Comments
 (0)