Templating using new RazorEngine API

C#Razor

C# Problem Overview


Some time ago rendering a template using RazorEngine was as easy as:

string s = RazorEngine.Razor.Parse()

However, for some reason, its authors changed their minds about the API and now the simplest way to render a template is:

var key = new RazorEngine.Templating.NameOnlyTemplateKey("EmailTemplate", RazorEngine.Templating.ResolveType.Global, null);
RazorEngine.Engine.Razor.AddTemplate(key, new RazorEngine.Templating.LoadedTemplateSource("Ala ma kota"));
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
RazorEngine.Engine.Razor.RunCompile(key, sw);
string s = sb.ToString();

(at least this is what I deduced from the new API. Old one is marked as deprecated.) Is there a way to use new API to render a template without caching, keys and other fancy stuff? All official examples simply doesn't work.

C# Solutions


Solution 1 - C#

Well, after searching the code, I found some useful examples (https://github.com/Antaris/RazorEngine/blob/master/src/source/RazorEngine.Hosts.Console/Program.cs) and found out that if you include

using RazorEngine.Templating;

at the top of your class, you can use some extension methods (https://github.com/Antaris/RazorEngine/blob/master/src/source/RazorEngine.Core/Templating/RazorEngineServiceExtensions.cs) that will help you.

Painless template compilation :

Engine.Razor.Compile(templatePath, "templateNameInTheCache", modelType);

Template Parsing :

Engine.Razor.Run("templateNameInTheCache", modelType, model);

And now you can do both at the same time !

string myParsedTemplate = Engine.Razor.RunCompile(templatePath, "templateNameInTheCache", null, model)

Which is the equivalent of doing this

Engine.Razor.AddTemplate("templateNameInTheCache", TemplateLoader.GetTemplate(templatePath));
Engine.Razor.Compile("templateNameInTheCache", modelType);
string finallyThisIsMyParsedTemplate = Engine.Razor.Run("templateNameInTheCache", modelType);

Please note that I'm currently testing this, but it seems to work fine.

Solution 2 - C#

The following code works for ResolvePathTemplateManager (October, 2017):

var templateManager = new ResolvePathTemplateManager(new[] { rootPath });

var config = new TemplateServiceConfiguration
{
	TemplateManager = templateManager
};

Engine.Razor = RazorEngineService.Create(config);

// ...

var html = Engine.Razor.RunCompile("Test.cshtml", null, model);

Source: in RazorEngineServiceTestFixture.cs, look for ResolvePathTemplateManager.

Solution 3 - C#

Building on @turdus-merula's answer, I wanted the temp files to be cleaned up when the default AppDomain is unloaded. I disabled the temp file locking in the config, which allows the temp folder to be deleted.

var config = new TemplateServiceConfiguration
{
    TemplateManager = new ResolvePathTemplateManager(new[] {"EmailTemplates"}),
    DisableTempFileLocking = true
};

Engine.Razor = RazorEngineService.Create(config);

var html = Engine.Razor.RunCompile("Test.cshtml", null, model);

Solution 4 - C#

Just FYI, using the RazorEngine API leads to memory leak. There is an official issue reported, that compiling templates keeps generating temp files that are very hard to get rid of. So be very careful if you use this in production.

Last I used this, it kept adding +1MB to memory on every template compilation, even when using cached templates!

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSpookView Question on Stackoverflow
Solution 1 - C#JJPView Answer on Stackoverflow
Solution 2 - C#turdus-merulaView Answer on Stackoverflow
Solution 3 - C#ConnorView Answer on Stackoverflow
Solution 4 - C#stann1View Answer on Stackoverflow