Quickly render Razor components to strings and TextWriters.
Install-Package RazorString
It should start out looking something like this:
<Project Sdk="Microsoft.NET.Sdk.Razor">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="8.0.3" />
</ItemGroup>
</Project>
The important things are that:
- Is is a
Microsoft.NET.Sdk.Razor
project - It references
Microsoft.AspNetCore.Components.Web
Get creative! You can keep things simple or complex.
Here's a fun example.
Create a file named Composite.razor
:
Hello @Context.Name! I see that you were born on @Context.Date_Of_Birth.
Today we will eat:
Breakfast: @Breakfast
Lunch: @Lunch
Dinner: @Dinner
@code {
[Parameter]
public required CompositeContext Context { get; init; }
[Parameter]
public required string Breakfast { get; init; }
[Parameter]
public required string Lunch { get; init; }
[Parameter]
public required string Dinner { get; init; }
}
Then also create a file named CompositeContext.cs
:
namespace Example.Templates {
public record CompositeContext {
public required string Name { get; init; }
public required DateTime Date_Of_Birth { get; init; }
}
}
var Template = TemplateFactory.Default.FromComponent<Composite>()
.WithParameters([
("Breakfast", "Coffee"),
("Lunch", "Sandwich"),
("Dinner", "Pizza"),
("Context", new CompositeContext() {
Name = "John Smith",
Date_Of_Birth = new DateTime(1901, 01, 01),
})
]);
var Content = await Template.RenderAsync();
Console.WriteLine(Content);
If your Razor templates have a property named Context
:
@code {
[Parameter]
public required CompositeContext Context { get; init; }
}
You can pass in that argument with:
var Template = TemplateFactory.Default.FromComponent<Composite>()
.WithContext(new CompositeContext() {
Name = "John Smith",
Date_Of_Birth = new DateTime(1901, 01, 01),
});
If you're going to use the same template in a loop, reuse it:
var Template = TemplateFactory.Default.FromComponent<Composite>();
foreach(var item in DataSet){
var Derived = Template
.WithParameters([
("Breakfast", item.Breakfast),
("Lunch", item.Lunch),
("Dinner", item.Dinner),
("Context", new CompositeContext() {
Name = item.Name,
Date_Of_Birth = item.DoB,
}),
]);
var Content = await Derived.RenderAsync();
Console.WriteLine(Content);
}
You don't have to provide all the args at once and you can override values.
//Load our base template with no args
var EmptyTemplate = TemplateFactory.Default.FromComponent<Composite>();
//Set some values
var TemplateWithDefaults = EmptyTemplate
.WithParameters([
("Context", new CompositeContext() {
Name = "John Smith",
Date_Of_Birth = new DateTime(1901, 01, 01),
}),
("Breakfast", "Coffee"),
]);
foreach(var Meal in Meals){
var MealPlan = TemplateWithDefaults
.WithParameters([
("Breakfast", Meal.Breakfast), //Override the default
("Lunch", Meal.Lunch),
("Dinner", Meal.Dinner),
]);
var Content = await MealPlan.RenderAsync();
Console.WriteLine(Content);
}