C# RazorEngine 3.7.7-编译缓存模板时出错

C# RazorEngine 3.7.7-编译缓存模板时出错,c#,wcf,razorengine,C#,Wcf,Razorengine,我试图找出最近RazorEngine 3.7.5及更高版本(试用3.7.7)出现的一个问题 例外情况: System.ArgumentException:请将模板管理器设置为templates或添加模板“MySolution.Billing.templates.Layout.cshtml” 尝试使用Engine.Razor.Compile方法缓存模板时发生此错误 public void AddTemplate(string templateName, string source) {

我试图找出最近RazorEngine 3.7.5及更高版本(试用3.7.7)出现的一个问题

例外情况:

System.ArgumentException:请将模板管理器设置为templates或添加模板“MySolution.Billing.templates.Layout.cshtml”

尝试使用Engine.Razor.Compile方法缓存模板时发生此错误

public void AddTemplate(string templateName, string source)
{
     Engine.Razor.AddTemplate(templateName, source);
}

public void CacheTemplate(string templateName, Type type)
{
     var templateKey = new NameOnlyTemplateKey(templateName, ResolveType.Layout, null);
     Engine.Razor.Compile(templateKey, type);
}
使用StructureMap for Instanceation创建包含PreloadTemplates方法的服务时,将调用PreloadTemplates方法。每个模板都存储为嵌入式资源,并加载到RazorEngine缓存中,然后立即使用RazorEngine进行编译,以确保所有模板尽可能快地加载

private void PreloadTemplates()
{
        var embeddedResources = Assembly.GetExecutingAssembly().GetManifestResourceNames().Where(x => x.StartsWith("MySolution.Billing.Templates")).ToList();
        foreach (var invoiceResource in embeddedResources)
        {
            using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(invoiceResource))
            {
                using (var reader = new StreamReader(stream))
                {
                    var template = reader.ReadToEnd();
                    this._templatingService.AddTemplate(invoiceResource, template);
                }
            }
        }

        this._templatingService.CacheTemplate("MySolution.Billing.Templates.Header.cshtml", typeof(HeaderModel));
        this._templatingService.CacheTemplate("MySolution.Billing.Templates.Layout.cshtml", typeof(LayoutModel));
        this._templatingService.CacheTemplate("MySolution.Billing.Templates.Footer.cshtml", null);
}
RazorEngine的配置如下

var config = new TemplateServiceConfiguration();
config.CachingProvider = new DefaultCachingProvider(t => { });
config.DisableTempFileLocking = true;
我们如何使用RazorEngine,应用程序流程

  • WCF(发票查询中心)
    • Global.asax.cs寄存器结构映射注册表
  • IInvoiceService(由StructureMap实例化以提供InvoiceService)
    • 该服务在其构造函数中调用预加载模板
  • 复制步骤


    我们几乎每次都可以通过停止IIS并重新启动它并调用WCF方法来重现错误。这似乎是回收应用程序池或停止IIS的问题,因为在WCF“预热”后错误不会再次出现。

    毕竟我自己能够找到答案

    我修改了我的TemplatingService类,如下所示

    public class TemplatingService : ITemplatingService
    {
        private readonly IRazorEngineService _razorEngineService;
    
        public TemplatingService(Assembly assembly, string templatesNamespace)
        {
            var config = new TemplateServiceConfiguration();
            config.TemplateManager = new EmbeddedResourceTemplateService(assembly, templatesNamespace);
    
    #if DEBUG
            config.Debug = true;
    #endif
    
            this._razorEngineService = RazorEngineService.Create(config);
        }
    
        public void CacheTemplate(string templateName, Type type)
        {
            var templateKey = new NameOnlyTemplateKey(templateName, ResolveType.Layout, null);
            this._razorEngineService.Compile(templateKey, type);
        }
    
        public string RunTemplate(string templateName, Type type, object model, IDictionary<string, object> dynamicViewBag = null)
        {
            var templateKey = new NameOnlyTemplateKey(templateName, ResolveType.Layout, null);
            return this._razorEngineService.RunCompile(templateKey, type, model, dynamicViewBag != null ? new DynamicViewBag(dynamicViewBag) : null);
        }
    }
    
    我希望这对其他人有帮助

    this.For<ITemplatingService>()
                .Singleton()
                .Add<TemplatingService>()
                .Named("invoiceTemplates")
                .Ctor<Assembly>("assembly").Is(billingDocumentGeneratorAssembly)
                .Ctor<string>("templatesNamespace").Is("MyBillingNamespace.DocumentGenerator.Invoices.Templates");
    
    var footerHtml = this._templatingService.RunTemplate("Footer.cshtml", null, null);
    var headerHtml = this._templatingService.RunTemplate("Header.cshtml", typeof(AccountStatementHeaderModel), accountStatementModel.Header);