.NET6 Razor Template Engine. No legacy code. No breaking changes.
Every single star makes maintainer happy! β
Install-Package RazorEngineCore
β Feel free to create new issues and vote for existing ones!
template.Run(object model = null)
template.RunAsync(object model = null)
template.Run<TModel>(TModel model = null)
template.RunAsync<TModel>(TModel model = null)
RazorEngineCore is not HTML safe by default. \ It can be easily turned on: see #65 and @Raw
IRazorEngine razorEngine = new RazorEngine();
IRazorEngineCompiledTemplate template = razorEngine.Compile("Hello @Model.Name");
string result = template.Run(new
{
Name = "Alexander"
});
Console.WriteLine(result);
IRazorEngine razorEngine = new RazorEngine();
string templateText = "Hello @Model.Name";
// yeah, heavy definition
IRazorEngineCompiledTemplate<RazorEngineTemplateBase<TestModel>> template = razorEngine.Compile<RazorEngineTemplateBase<TestModel>>(templateText);
string result = template.Run(instance =>
{
instance.Model = new TestModel()
{
Name = "Hello",
Items = new[] {3, 1, 2}
};
});
Console.WriteLine(result);
Compile template with IncludeDebuggingInfo()
option and call EnableDebugging()
before running template. If template was compiled with IncludeDebuggingInfo()
option, saving and loading will keep original template source code and pdb.
IRazorEngineCompiledTemplate template2 = razorEngine.Compile(templateText, builder =>
{
builder.IncludeDebuggingInfo();
});
template2.EnableDebugging(); // optional path to output directory
string result = template2.Run(new
{
Title = "Welcome"
});
Place @{ Breakpoint(); }
anywhere in template to stop at.
Most expensive task is to compile template, you should not compile template every time you need to run it
IRazorEngine razorEngine = new RazorEngine();
IRazorEngineCompiledTemplate template = razorEngine.Compile("Hello @Model.Name");
// save to file
template.SaveToFile("myTemplate.dll");
//save to stream
MemoryStream memoryStream = new MemoryStream();
template.SaveToStream(memoryStream);
IRazorEngineCompiledTemplate template1 = RazorEngineCompiledTemplate.LoadFromFile("myTemplate.dll");
IRazorEngineCompiledTemplate template2 = RazorEngineCompiledTemplate.LoadFromStream(myStream);
IRazorEngineCompiledTemplate<MyBase> template1 = RazorEngineCompiledTemplate<MyBase>.LoadFromFile<MyBase>("myTemplate.dll");
IRazorEngineCompiledTemplate<MyBase> template2 = RazorEngineCompiledTemplate<MyBase>.LoadFromStream<MyBase>(myStream);
RazorEngineCore is not responsible for caching. Each team and project has their own caching frameworks and conventions therefore making it impossible to have builtin solution for all possible needs.
If you dont have one, use following static ConcurrentDictionary example as a simplest thread safe solution.
private static ConcurrentDictionary<int, IRazorEngineCompiledTemplate> TemplateCache = new ConcurrentDictionary<int, IRazorEngineCompiledTemplate>();
private string RenderTemplate(string template, object model)
{
int hashCode = template.GetHashCode();
IRazorEngineCompiledTemplate compiledTemplate = TemplateCache.GetOrAdd(hashCode, i =>
{
RazorEngine razorEngine = new RazorEngine();
return razorEngine.Compile(Content);
});
return compiledTemplate.Run(model);
}
ASP.NET Core way of defining template functions:
<area>
@{ RecursionTest(3); }
</area>
@{
void RecursionTest(int level)
{
if (level <= 0)
{
return;
}
<div>LEVEL: @level</div>
@{ RecursionTest(level - 1); }
}
}
output:
<div>LEVEL: 3</div>
<div>LEVEL: 2</div>
<div>LEVEL: 1</div>
string content = @"Hello @A, @B, @Decorator(123)";
IRazorEngine razorEngine = new RazorEngine();
IRazorEngineCompiledTemplate<CustomTemplate> template = razorEngine.Compile<CustomTemplate>(content);
string result = template.Run(instance =>
{
instance.A = 10;
instance.B = "Alex";
});
Console.WriteLine(result);
public class CustomTemplate : RazorEngineTemplateBase
{
public int A { get; set; }
public string B { get; set; }
public string Decorator(object value)
{
return "-=" + value + "=-";
}
}
Keep your templates as simple as possible, if you need to inject "unusual" assemblies most likely you are doing it wrong.
Writing @using System.IO
in template will not reference System.IO assembly, use builder to manually reference it.
IRazorEngine razorEngine = new RazorEngine();
IRazorEngineCompiledTemplate compiledTemplate = razorEngine.Compile(templateText, builder =>
{
builder.AddAssemblyReferenceByName("System.Security"); // by name
builder.AddAssemblyReference(typeof(System.IO.File)); // by type
builder.AddAssemblyReference(Assembly.Load("source")); // by reference
});
string result = compiledTemplate.Run(new { name = "Hello" });
This package is inspired by Simon Mourier SO post