编程语言
首页 > 编程语言> > c# – RazorEngine 3.7.7 – 编译缓存模板时出错

c# – RazorEngine 3.7.7 – 编译缓存模板时出错

作者:互联网

我试图找出我们最近使用RazorEngine 3.7.5及更高版本的问题(试过3.7.7)

例外:

System.ArgumentException: Please either set a template manager to templates or add the template ‘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,应用程序的流程

> WCF(InvoiceQueryFacade)

> Global.asax.cs注册StructureMap注册表

> IInvoiceService(由StructureMap实现提供InvoiceService)

>该服务在其构造函数中调用PreloadTemplates

重现步骤

我们几乎每次都可以通过停止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);
    }
}

我开始使用官方网站上的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");

我可以使用TemplatingService,如下所示

var footerHtml = this._templatingService.RunTemplate("Footer.cshtml", null, null);
var headerHtml = this._templatingService.RunTemplate("Header.cshtml", typeof(AccountStatementHeaderModel), accountStatementModel.Header);

我希望这可以帮助别人.

标签:c,wcf,razorengine
来源: https://codeday.me/bug/20190516/1116003.html