After upgrading from Razor templating engine 3.3.0 to 3.6.1 I've run into issues with precompiled templates - what happens is that even the trivial sample given on their page:
using System;
using RazorEngine;
using RazorEngine.Templating;
using System.Diagnostics;
namespace RazorTest
{
class Program
{
static void Main(string[] args)
{
string template = "Hello @Model.Name, welcome to RazorEngine!";
Debug.WriteLine("Before Compile()");
var result = Engine.Razor.RunCompile(template, "templateKey", null, new { Name = "World" });
Debug.WriteLine("After Compile()");
}
}
}
Throws System.UnauthorizedAccessException
on exit when trying to delete the generated dll files. The debug output shows everything quite nicely:
Before Compile()
'RazorTest.vshost.exe' (Managed (v4.0.30319)): Loaded 'C:\Users\user\Documents\Visual Studio 2010\Projects\RazorTest\RazorTest\bin\Debug\System.Web.Razor.dll'
'RazorTest.vshost.exe' (Managed (v4.0.30319)): Loaded 'C:\Users\user\AppData\Local\Temp\RazorEngine_zzxr14ak.ysb\CompiledRazorTemplates.Dynamic.RazorEngine_dc2066212315402592a6d2d155476c19.dll'
'RazorTest.vshost.exe' (Managed (v4.0.30319)): Loaded 'Anonymously Hosted DynamicMethods Assembly'
'RazorTest.vshost.exe' (Managed (v4.0.30319)): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Dynamic\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Dynamic.dll'
A first chance exception of type 'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException' occurred in Microsoft.CSharp.dll
A first chance exception of type 'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException' occurred in Microsoft.CSharp.dll
After Compile()
The thread 'vshost.RunParkingWindow' (0x3064) has exited with code 0 (0x0).
The thread '<No Name>' (0x2df0) has exited with code 0 (0x0).
A first chance exception of type 'System.UnauthorizedAccessException' occurred in mscorlib.dll
A first chance exception of type 'System.UnauthorizedAccessException' occurred in mscorlib.dll
A first chance exception of type 'System.UnauthorizedAccessException' occurred in mscorlib.dll
The program '[26908] RazorTest.vshost.exe: Managed (v4.0.30319)' has exited with code 0 (0x0).
The dll file is loaded by the application during compilation so it makes sense that if some kind of unloading is not done Razor will not be able to delete it, and the files are left on the disk.
What else seems weird that even though the type of the model is given Razor considers the template to be dynamic (at least judging from the dll name).
Has anyone more experienced with Razor encountered this or can provide some hints on how to overcome this issue?
There was a problem with temporary files, which has been fixed in 3.6.4 (for the most part). If you want details please read https://github.com/Antaris/RazorEngine/issues/244. There are still first chance exceptions of type 'System.UnauthorizedAccessException'
, but they handled internally by RazorEngine.
Your template is in fact compiled with dyanmic
as model-type because you have given null = dynamic
as the modeltype
parameter.
If you want to compile your template with a static type use
Engine.Razor.RunCompile(template, "templateKey", typeof(MyModel), new MyModel());
The reason we made the type explicit is because you can now re-use the same template for multiple types by either specifying a common base type or by explicitly using null = dynamic
:
// Will compile only once
Engine.Razor.RunCompile(template, "templateKey", typeof(MyBaseModel), new MyModel1());
Engine.Razor.RunCompile(template, "templateKey", typeof(MyBaseModel), new MyModel2());
// Will start a new compilation, and load another assembly
Engine.Razor.RunCompile(template, "templateKey", typeof(MyModel3), new MyModel3());
this works as long as MyModel1
and MyMode2
inherit from MyBaseModel
. Or you can use dynamic:
// Will compile only once
Engine.Razor.RunCompile(template, "templateKey", null, new FirstModel());
Engine.Razor.RunCompile(template, "templateKey", null, new SecondModel());
Note that with dynamic your models don't even need to inherit from the same base type. As long as FirstModel
and SecondModel
have all properties, which are required by the template, it will work (but it will fail not at template-compilation but at template-runtime).
This is especially useful for included and layout templates (which is a lot more customizable now).
Hope this helps. matthid, a RazorEngine contributor.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With