loyouyang / RazorEngineCore

ASP.NET Core 3.1.4 Razor Template Engine

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

RazorEngineCore

NETCore 3.1.4 Razor Template Engine. No legacy code.

  • .NET Standard 2.0

NuGet NuGet Gitter

Every single star makes maintainer happy! ⭐

NuGet

Install-Package RazorEngineCore

Articles

Wiki

Examples

Basic usage

RazorEngine razorEngine = new RazorEngine();
RazorEngineCompiledTemplate template = razorEngine.Compile("Hello @Model.Name");

string result = template.Run(new
{
    Name = "Alexander"
});

Console.WriteLine(result);

Strongly typed model

string templateText = "Hello @Model.Name";

// yeah, heavy definition
RazorEngineCompiledTemplate<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);

Save / Load compiled templates

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

RazorEngine razorEngine = new RazorEngine();
RazorEngineCompiledTemplate template = razorEngine.Compile("Hello @Model.Name");

// save to file
template.SaveToFile("myTemplate.dll");

//save to stream
MemoryStream memoryStream = new MemoryStream();
template.SaveToStream(memoryStream);
RazorEngineCompiledTemplate template1 = RazorEngineCompiledTemplate.LoadFromFile("myTemplate.dll");
RazorEngineCompiledTemplate template2 = RazorEngineCompiledTemplate.LoadFromStream(myStream);
RazorEngineCompiledTemplate<MyBase> template1 = RazorEngineCompiledTemplate<MyBase>.LoadFromFile<MyBase>("myTemplate.dll");
RazorEngineCompiledTemplate<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.

private static ConcurrentDictionary<string, RazorEngineCompiledTemplate> TemplateCache = new ConcurrentDictionary<string, RazorEngineCompiledTemplate>();
private string RenderTemplate(string template, object model)
{
    int hashCode = template.GetHashCode();

    RazorEngineCompiledTemplate compiledTemplate = TemplateCache.GetOrAdd(hashCode, i =>
    {
        RazorEngine razorEngine = new RazorEngine();
        return razorEngine.Compile(Content);
    });

    return compiledTemplate.Run(model);
}

Template functions

ASP.NET Core 3 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

string content = @"Hello @A, @B, @Decorator(123)";

RazorEngine razorEngine = new RazorEngine();
RazorEngineCompiledTemplate<CustomModel> template = razorEngine.Compile<CustomModel>(content);

string result = template.Run(instance =>
{
    instance.A = 10;
    instance.B = "Alex";
});

Console.WriteLine(result);
public class CustomModel : RazorEngineTemplateBase
{
    public int A { get; set; }
    public string B { get; set; }

    public string Decorator(object value)
    {
        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.

RazorEngine razorEngine = new RazorEngine();
RazorEngineCompiledTemplate 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" });

Credits

This package is inspired by Simon Mourier SO post

Changelog

  • 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

About

ASP.NET Core 3.1.4 Razor Template Engine

License:MIT License


Languages

Language:C# 99.4%Language:PowerShell 0.6%