2016-02-19 141 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。