Render Razor components outside of ASP.NET Core
Note
This isn't the latest version of this article. For the current release, see the .NET 9 version of this article.
Important
This information relates to a pre-release product that may be substantially modified before it's commercially released. Microsoft makes no warranties, express or implied, with respect to the information provided here.
For the current release, see the .NET 9 version of this article.
Razor components can be rendered outside of the context of an HTTP request. You can render Razor components as HTML directly to a string or stream independently of the ASP.NET Core hosting environment. This is convenient for scenarios where you want to generate HTML fragments, such as for generating email content, generating static site content, or for building a content templating engine.
In the following example, a Razor component is rendered to an HTML string from a console app:
In a command shell, create a new console app project:
dotnet new console -o ConsoleApp1
cd ConsoleApp1
In a command shell in the ConsoleApp1
folder, add package references for Microsoft.AspNetCore.Components.Web and Microsoft.Extensions.Logging to the console app:
dotnet add package Microsoft.AspNetCore.Components.Web
dotnet add package Microsoft.Extensions.Logging
In the console app's project file (ConsoleApp1.csproj
), update the console app project to use the Razor SDK:
- <Project Sdk="Microsoft.NET.Sdk">
+ <Project Sdk="Microsoft.NET.Sdk.Razor">
Add the following RenderMessage
component to the project.
RenderMessage.razor
:
<h1>Render Message</h1>
<p>@Message</p>
@code {
[Parameter]
public string Message { get; set; }
}
Update the Program
file:
- Set up dependency injection (IServiceCollection/BuildServiceProvider) and logging (AddLogging/ILoggerFactory).
- Create an HtmlRenderer and render the
RenderMessage
component by calling RenderComponentAsync.
Any calls to RenderComponentAsync must be made in the context of calling InvokeAsync
on a component dispatcher. A component dispatcher is available from the HtmlRenderer.Dispatcher property.
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using ConsoleApp1;
IServiceCollection services = new ServiceCollection();
services.AddLogging();
IServiceProvider serviceProvider = services.BuildServiceProvider();
ILoggerFactory loggerFactory = serviceProvider.GetRequiredService<ILoggerFactory>();
await using var htmlRenderer = new HtmlRenderer(serviceProvider, loggerFactory);
var html = await htmlRenderer.Dispatcher.InvokeAsync(async () =>
{
var dictionary = new Dictionary<string, object?>
{
{ "Message", "Hello from the Render Message component!" }
};
var parameters = ParameterView.FromDictionary(dictionary);
var output = await htmlRenderer.RenderComponentAsync<RenderMessage>(parameters);
return output.ToHtmlString();
});
Console.WriteLine(html);
Note
Pass ParameterView.Empty to RenderComponentAsync when rendering the component without passing parameters.
Alternatively, you can write the HTML to a TextWriter by calling output.WriteHtmlTo(textWriter)
.
The task returned by RenderComponentAsync completes when the component is fully rendered, including completing any asynchronous lifecycle methods. If you want to observe the rendered HTML earlier, call BeginRenderingComponent instead. Then, wait for the component rendering to complete by awaiting HtmlRootComponent.QuiescenceTask on the returned HtmlRootComponent instance.
ASP.NET Core