Skip to content

Repository files navigation

RazorEngineCore

.NET6 Razor Template Engine. No legacy code. No breaking changes.

  • .NET 6.0
  • .NET 5.0
  • .NET Standard 2.0
  • .NET Framework 4.7.2
  • Windows / Linux
  • Publish as single file supported
  • Thread safe

NuGetNuGetGitter

Every single star makes maintainer happy! ⭐

NuGet

Install-Package RazorEngineCore

Feature requests

✅ Feel free to create new issues and vote for existing ones!

Articles

Wiki

Extensions

  • wdcossey/RazorEngineCore.Extensions
    • HTML values encoded by default (See issue #65 and @Raw)
    • Template precompiling
    • Direct model usage without RazorEngineTemplateBase
    template.Run(objectmodel=null)
    template.RunAsync(objectmodel=null)template.Run<TModel>(TModelmodel=null)
    template.RunAsync<TModel>(TModelmodel=null)

💥 HTML Safety

RazorEngineCore is not HTML safe by default.
It can be easily turned on: see #65 and @Raw

Examples

Basic usage

IRazorEnginerazorEngine=newRazorEngine();IRazorEngineCompiledTemplatetemplate=razorEngine.Compile("Hello @Model.Name");stringresult=template.Run(new{Name="Alexander"});Console.WriteLine(result);

Strongly typed model

IRazorEnginerazorEngine=newRazorEngine();stringtemplateText="Hello @Model.Name";// yeah, heavy definitionIRazorEngineCompiledTemplate<RazorEngineTemplateBase<TestModel>>template=razorEngine.Compile<RazorEngineTemplateBase<TestModel>>(templateText);stringresult=template.Run(instance =>{instance.Model=newTestModel(){Name="Hello",Items=new[]{3,1,2}};});Console.WriteLine(result);

Save / Load compiled templates

Most expensive task is to compile template, you should not compile template every time you need to run it

IRazorEnginerazorEngine=newRazorEngine();IRazorEngineCompiledTemplatetemplate=razorEngine.Compile("Hello @Model.Name");// save to filetemplate.SaveToFile("myTemplate.dll");//save to streamMemoryStreammemoryStream=newMemoryStream();template.SaveToStream(memoryStream);
IRazorEngineCompiledTemplatetemplate1=RazorEngineCompiledTemplate.LoadFromFile("myTemplate.dll");IRazorEngineCompiledTemplatetemplate2=RazorEngineCompiledTemplate.LoadFromStream(myStream);
IRazorEngineCompiledTemplate<MyBase>template1=RazorEngineCompiledTemplate<MyBase>.LoadFromFile<MyBase>("myTemplate.dll");IRazorEngineCompiledTemplate<MyBase>template2=RazorEngineCompiledTemplate<MyBase>.LoadFromStream<MyBase>(myStream);

Caching

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.

privatestaticConcurrentDictionary<int,IRazorEngineCompiledTemplate>TemplateCache=newConcurrentDictionary<int,IRazorEngineCompiledTemplate>();
privatestringRenderTemplate(stringtemplate,objectmodel){inthashCode=template.GetHashCode();IRazorEngineCompiledTemplatecompiledTemplate=TemplateCache.GetOrAdd(hashCode, i =>{RazorEnginerazorEngine=newRazorEngine();returnrazorEngine.Compile(Content);});returncompiledTemplate.Run(model);}

Template functions

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>

Helpers and custom members

stringcontent=@"Hello @A, @B, @Decorator(123)";IRazorEnginerazorEngine=newRazorEngine();IRazorEngineCompiledTemplate<CustomModel>template=razorEngine.Compile<CustomModel>(content);stringresult=template.Run(instance =>{instance.A=10;instance.B="Alex";});Console.WriteLine(result);
publicclassCustomModel:RazorEngineTemplateBase{publicintA{get;set;}publicstringB{get;set;}publicstringDecorator(objectvalue){return"-="+value+"=-";}}

Referencing assemblies

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.

IRazorEnginerazorEngine=newRazorEngine();IRazorEngineCompiledTemplatecompiledTemplate=razorEngine.Compile(templateText, builder =>{builder.AddAssemblyReferenceByName("System.Security");// by namebuilder.AddAssemblyReference(typeof(System.IO.File));// by typebuilder.AddAssemblyReference(Assembly.Load("source"));// by reference});stringresult=compiledTemplate.Run(new{name="Hello"});

Credits

This package is inspired by Simon Mourier SO post

Changelog

  • 2022.8.1
    • Proper namespace handling for nested types and types without namespace #113 (thanks @Kirmiir)
  • 2022.1.2
    • #94 publish as single file fix
  • 2022.1.1
    • Make private methods in RazorEngine protected and virtual #PR88 (thanks @wdcossey)
    • Dictionary bug in anonymous model #91 (thanks @jddj007-hydra)
    • Template name fix #PR84 (thanks @Yazwh0)
    • CI for GitHub Actions #PR69 (thanks @304NotModified)
    • Added Source Link #PR67 (thanks @304NotModified)
    • Microsoft.AspNetCore.Razor.Language 3.1.8 -> 6.0.1
    • Microsoft.CodeAnalysis.CSharp 3.7.0 -> 4.0.1
  • 2021.7.1
  • 2021.3.1
    • fixed NET5 publish as single file (thanks @jddj007-hydra)
    • AnonymousTypeWrapper array handling fix
    • System.Collections referenced by default
    • Microsoft.AspNetCore.Razor.Language 3.1.8 -> 5.0.3
    • Microsoft.CodeAnalysis.CSharp 3.7.0 -> 3.8.0
  • 2020.10.1
    • Linux fix for #34
    • Microsoft.AspNetCore.Razor.Language 3.1.5 -> 3.1.8
    • Microsoft.CodeAnalysis.CSharp 3.6.0 -> 3.7.0
  • 2020.9.1
    • .NET 4.7.2 support (thanks @krmr)
  • 2020.6.1
    • Reference assemblies by Metadata (thanks @Merlin04)
    • Expose GeneratedCode in RazorEngineCompilationException
    • Microsoft.AspNetCore.Razor.Language 3.1.4 -> 3.1.5
  • 2020.5.2
    • IRazorEngineTemplate interface
    • RazorEngineTemplateBase methods go virtual
  • 2020.5.1
    • Async methods (thanks @wdcossey)
    • Microsoft.AspNetCore.Razor.Language 3.1.1 -> 3.1.4
    • Microsoft.CodeAnalysis.CSharp 3.4.0 -> 3.6.0
  • 2020.3.3
    • Model with generic type arguments compiling fix
  • 2020.3.2
    • External assembly referencing
    • Linq included by default
  • 2020.3.1
    • In attribute rendering fix #4
  • 2020.2.4
    • Null values in model correct handling
    • Null model fix
    • Netstandard2 insted of netcore3.1
  • 2020.2.3
    • Html attribute rendering fix
    • Html attribute rendering tests

Supported by

About

.NET5 Razor Template Engine

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages