2016-02-19 112 views
4

我想弄清楚的问题,我们一直在与RazorEngine 3.7.5及更高版本(3.7.7试过)RazorEngine 3.7.7 - 错误编译缓存模板

异常最近有当:

System.ArgumentException:请将模板管理器设置为模板或添加模板'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创建包含它的服务时,将调用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,应用

  1. WCF(InvoiceQueryFacade)
    • Global.asax中的流动。 cs注册StructureMap注册表
  2. IInvoiceService(由StructureMap实例化提供一个InvoiceService)
    • 服务调用PreloadTemplates在它的构造

步骤来重现

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

回答

5

我终于可以自己找到答案了。

我修改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); 
    } 
} 

我开始使用TemplatingManager从官方网站:RazorEngine string layouts and sections?,它似乎已经完成了帽子戏法。

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); 

我希望这种帮助别人使用TemplatingService。