简体   繁体   English

Razor无法删除动态模板DLL文件并删除文件系统

[英]Razor fails to delete dynamic template dll files and trashes filesystem

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: 从Razor模板引擎3.3.0升级到3.6.1后,我遇到了预编译模板的问题 - 即使是在页面上给出的琐碎样本,也会发生这样的事情:

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. 尝试删除生成的dll文件时,在退出时抛出System.UnauthorizedAccessException 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. 应用程序在编译期间加载了dll文件,因此如果没有进行某种卸载,Razor将无法删除它,并且文件将保留在磁盘上。

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). 即使模型的类型被赋予Razor认为模板是动态的(至少从dll名称判断),还有什么看起来很奇怪。

Has anyone more experienced with Razor encountered this or can provide some hints on how to overcome this issue? 有没有更多经验的Razor遇到过这个或者可以提供一些如何克服这个问题的提示?

There was a problem with temporary files, which has been fixed in 3.6.4 (for the most part). 临时文件存在问题,已在3.6.4(大部分)中修复。 If you want details please read https://github.com/Antaris/RazorEngine/issues/244 . 如果您需要详细信息,请阅读https://github.com/Antaris/RazorEngine/issues/244 There are still first chance exceptions of type 'System.UnauthorizedAccessException' , but they handled internally by RazorEngine. 仍然first chance exceptions of type 'System.UnauthorizedAccessException' ,但它们由RazorEngine内部处理。

Your template is in fact compiled with dyanmic as model-type because you have given null = dynamic as the modeltype parameter. 实际上,您的模板使用dyanmic作为模型类型进行编译,因为您已将null = dynamic作为modeltype参数。

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 : 我们将类型显式化的原因是,您现在可以通过指定公共基类型或显式使用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 . 只要MyModel1MyMode2继承自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). 只要FirstModelSecondModel具有模板所需的所有属性,它就可以工作(但它不会在模板编译时失败,而是在模板运行时失败)。

This is especially useful for included and layout templates (which is a lot more customizable now). 这对包含和布局模板特别有用(现在可以更加自定义)。

Hope this helps. 希望这可以帮助。 matthid, a RazorEngine contributor. matthid,RazorEngine的贡献者。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM