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

标签 c# wcf razorengine

我正在尝试找出我们最近在使用 RazorEngine 3.7.5 及更高版本(尝试过 3.7.7)时遇到的问题

异常(exception):

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,应用程序的流程

  1. WCF(发票查询门面)
    • Global.asax.cs 注册 StructureMap 注册中心
  2. 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# - RazorEngine 3.7.7 - 编译缓存模板时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35512454/

相关文章:

RazorEngine 3.2.0 : Razor Namespace not found in . cshtml 文件

c# - 如何在字符串中嵌入 Razor 变量?

c# - 在 MVC 之外使用 Razor 模板引擎(具有完整的 mvc razor 支持)

c# - 使用 jQuery 在 ASP.NET MVC 5 应用程序中调用 Web API 服务

c# - 我们需要使用 SqlCommand 还是仅用于 SqlConnection 和 SqlDataReader

c# - 无法替换字符串列表中的最后一个元素

c# - 适用于 Windows 应用商店应用的 ServicePoint.Expect100Continue

wcf - 使用定位器管理全景页面中的多个 View - View 模型对

c# - 等到多个命令行进程完成?

wcf - 将服务引用添加到 net.pipe 服务