问题
我正在将我们的主要项目迁移到Net5,它的主要特性是使用RazorEngine生成文档。将所有内容迁移到Net5之后,应用程序将按预期运行,但RazorEngine除外。在进行了相当多的测试之后,我发现RazorEngine.NetCore缺少了一些功能,或者已经被重构为不同的功能。
第一个问题是,RazorEngine.NetCore不支持作为其前身的所有语法,例如@函数。我在github上找到了一个分叉版本,这个版本需要更多的努力才能实现,但确实有效。然而,管理层更希望这是一个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, templateKey, null, model, viewBag);结果
string preProcessedTemplate = "@{const string templatePath = @\"C:\\some\\other\\directory\\\";}...the template's contents..."
场景1:抛出异常
场景2:返回编译后的模板
问题
RazorEngine.Engine.Razor.RunCompile(...)只编译场景2?发布于 2021-05-13 10:42:16
如果“官方”指的是微软( Microsoft )生产的产品,那么怀疑这种情况很快就会发生。
请告诉我们具体的例外情况?
试试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);variables :第二个问题是,我们需要在每个模板中注入逻辑来创建变量(谁的值是在运行时确定的),这一点我还没有找到。
建议您将此逻辑移动到传递到视图的模型中,而不是修改cshtml。明显的坚实的原理的好处和更容易测试的模型在隔离。这就是我们的团队在使用RazorLight生成文档时所做的事情。
https://stackoverflow.com/questions/67291339
复制相似问题