While rendering components on a server simply to get the string representation isn’t a usual practice in web development it does have some applications, such as create easy to edit email templates.
DotNet Core introduced the HtmlRenderer class, allowing razor components to be specified and rendered. In it’s simplest form it can be implemented like so:
public class Renderer(HtmlRenderer htmlRenderer)
{
public Task<string> RenderComponent<T>(Dictionary<string, object?> dictionary) where T : IComponent
=> RenderComponent<T>(ParameterView.FromDictionary(dictionary));
private Task<string> RenderComponent<T>(ParameterView parameters) where T : IComponent
{
return htmlRenderer.Dispatcher.InvokeAsync(async () =>
{
var output = await htmlRenderer.RenderComponentAsync<T>(parameters);
return output.ToHtmlString();
});
}
}
Let’s break this down a little.
RenderComponent takes a type of T
which is limited to IComponent
. This parameter takes a razor component. It is called with a Dictionary of objects using the key to specify which properties on a given component.
Given a razor component named MyComponent.razor
laid out like this:
<head>
<title></title>
</head>
<body>
<div>
<table>
<thead>
<tr>
<th>Error Name</th>
<th>Error Message</th>
</tr>
</thead>
<tbody>
@foreach (var error in Errors)
{
<tr>
<td>@error.Name</td>
<td>@error.Message</td>
</tr>
}
</tbody>
</table>
</div>
</body>
@code {
[Parameter]
public List<Error> Errors { get; set; } = [];
}
RenderComponent can be called like so:
renderer.RenderComponent<MyComponent>(new Dictionary<string, object?>{{"Errors", new List<Error>()}});
A last thing of note is the HtmlRenderer used in the Renderer class. The easiest way to provide this is to inject it in during startup, e.g.
using Microsoft.AspNetCore.Components.Web;
services.AddScoped<HtmlRenderer>();