Parse给出“;用于模拟的令牌无效-它不能重复“;当使用匿名模型和缓存名称时

本文关键字:缓存 模型 不能 模拟 用于 给出 令牌 无效 Parse | 更新日期: 2023-09-27 18:26:18

我遵循本教程使用RazorEngine生成HTML电子邮件(不使用ASP.NET MVC)。当我使用强类型视图或匿名对象作为模型时,它工作得很好:

Layout.cshtml

@model dynamic
// html contents...

C#代码段

var template = Encoding.UTF8.GetString(Properties.Resources.ContractList);
var model = new
{
    ContractList = list
};
var templateService = new TemplateService();
var html = templateService.Parse(template, model, null, null);

然后我给它起了一个缓存名称,正如教程的第三部分所建议的那样:

templateService.Parse(template, model, null, nameof(Properties.Resources.ContractList));

它在强类型对象上工作得很好,但在匿名对象上,我在第二次运行时就开始收到这个消息:

用于模拟的令牌无效-不能重复

如何解决此问题并仍然为模型使用匿名对象?

我看到过一些解决方案(这里,这里)建议将匿名对象转换为ExpandoObject,但如果可能的话,我希望避免这种情况。

Parse给出“;用于模拟的令牌无效-它不能重复“;当使用匿名模型和缓存名称时

在阅读RazorEngine文档后,我在它们的升级页面上发现了一些示例,其中展示了如何使用Engine.Razor。最简单的方法是:

var html = Engine.Razor.RunCompile(
    template,
    nameof(Properties.Resources.ContractList),
    null,
    model
);

这解决了问题。请注意,他们不建议使用上述格式,因为在内部,它每次都会调用AddTemplate,并且当您对不同的模板使用相同的cache_name时,它会抛出异常。相反,他们建议在启动时进行预编译:

// Once at startup (not required when using an ITemplateManager which knows how to
// resolve cache_name)
Engine.Razor.AddTemplate(cache_name, razorTemplate)
// On startup
Engine.Razor.Compile(
    cache_name, 
    typeof(MyModel) /* or model.GetType() or null for 'dynamic'*/
)
// instead of the Razor.Parse call
var result = Engine.Razor.Run(
    cache_name,
    typeof(MyModel), /* or model.GetType() or null for 'dynamic'*/
    model
)