RazorEngine.NetCore 不编译 TemplateSource

问题描述

问题

我正在将我们的主要项目迁移到 Net 5。它的主要功能是使用 RazorEngine 生成文档。将所有内容迁移到 Net5 后,应用程序按预期运行,但 RazorEngine 除外。经过大量测试后,我发现 RazorEngine.NetCore 缺少某些功能或已重构以使其功能不同。

一个问题是 RazorEngine.NetCore 不支持其前身的所有语法,例如 @functions。我在 github 上找到了一个 fork 版本,它需要更多的努力来实现但确实有效。但是,管理层更希望这是一个我们不必管理的 nuget 包。

我还没有找到解决办法的第二个问题是,我们需要将逻辑注入每个模板以创建变量(谁的值在运行时确定)。例如,我们确定一个目录位置并为一个 cshtml 文档创建一个代码块的字符串版本。该字符串在由 RazorEngine.Engine.Razor.runcompile(...) 处理之前连接到模板的内容。 RazorEngine 抛出异常,因为模板尝试使用注入的变量之一,但它不存在。如果我检查注入代码块与模板内容的完全连接字符串,然后手动将相同的代码块直接添加到模板中,它会按预期进行编译和运行。我手动将代码添加到模板中进行测试,但这不适用于生产,因此我们在这里

下面的代码一个被注入到模板中的代码块。如果将同一行添加为模板的第一行,则它会起作用。我不明白的是,提供给 RazorEngine.Engine.Razor.runcompile(...) 的字符串完全相同(无论下面的代码是与模板的内容连接还是字符串完全来自模板)。

场景 1 - 串联

report.cshtml:...the template's contents...

string templateReference = @"C:\templates\report.cshtml" // hard-coded here for simplicity
TemplateKey templateKey = (TemplateKey)Engine.Razor.GetKey(templateReference);
string path = @"C:\some\other\directory\";
string header = $"@{{const string templatePath = @\"{path}\";}}";
string templateContent = // contents of the report.cshtml file
string preProcessedTemplate = header + templateContent;
string output = Engine.Razor.runcompile(preProcessedTemplate,templateKey,null,model,viewBag);

场景 2 - 嵌入式

report.cshtml:@{const string templatePath = @"C:\some\other\directory\";}...the template's contents...

string templateReference = @"C:\templates\report.cshtml" // hard-coded here for simplicity
TemplateKey templateKey = (TemplateKey)Engine.Razor.GetKey(templateReference);
string preProcessedTemplate = // contents of the report.cshtml file
string output = Engine.Razor.runcompile(preProcessedTemplate,viewBag);

结果

string preProcessedTemplate = "@{const string templatePath = @\"C:\\some\\other\\directory\\\";}...the template's contents..."
场景一:抛出异常
场景二:返回编译好的模板

问题

  1. RazorEngine.NetCore 不是官方的 Microsoft RazorEngine。是否有正式版本的计划?
  2. 如果来自两个场景的字符串相同,为什么 RazorEngine.Engine.Razor.runcompile(...) 只编译场景 2?
  3. 是否有无需重构 cshtml 模板的 RazorEngine for Net 5 替代方案?

解决方法

  1. RazorEngine.NetCore 不是官方的 Microsoft RazorEngine。是否有正式版本的计划?

如果“官方”是指微软出品,怀疑这会很快发生。

  1. 如果来自两个场景的字符串相同,为什么 RazorEngine.Engine.Razor.RunCompile(...) 只编译场景 2?

请告诉我们确切的例外情况?

  1. 是否有无需重构 cshtml 模板的 RazorEngine for Net 5 替代方案?

试试RazorLight,它很酷而且效果很好。正如您所指出的,我已经尝试了一些“Razor 引擎”,其中许多已停用或不支持最新的官方 Razor 更新。我发现 RazorLight 是所有考虑中最好的。当然,RazorEngine 是一个较新的库,没有遗留问题,尽管我只是建议一个快速修复的替代选项。

RazorLight 的一些示例代码

var engine = new RazorLightEngineBuilder()
    .UseFileSystemProject("C:/RootFolder/With/YourTemplates")
    .UseMemoryCachingProvider()
    .Build();

var model = new {Name = "John Doe"};
string result = await engine.CompileRenderAsync("Subfolder/View.cshtml",model);

问题:我还没有找到解决办法的第二个问题是,我们需要将逻辑注入每个模板以创建变量(谁的值在运行时确定)。 >

建议您将此逻辑移到传递到视图中的模型中,而不是更改 cshtml。明显的 SOLID 原则有好处,并且更容易单独测试模型。这就是我们团队在使用 RazorLight 生成文档时所做的。