呈现电子邮件会在非MVC项目中使用RazorEngine 3抛出TemplateCompilationException

时间:2013-01-03 09:42:01

标签: razor template-engine razor-2

我正在尝试在Windows服务主机中呈现电子邮件。

我使用由coxp分叉的RazorEngine 3,它支持Razor 2。 https://github.com/coxp/RazorEngine/tree/release-3.0/src

这适用于几个电子邮件模板,但有一个导致我出现问题。

@model string

<a href="@Model" target="_blank">Click here</a> to enter a new password for your account.

抛出CompilationException:当前上下文中不存在名称“WriteAttribute”。因此,将字符串作为模型传入并将其放入href-attribute会导致问题。

我可以通过以下方式改变这一行:

@Raw(string.Format("<a href=\"{0}\" target=\"_blank\">Klik hier</a>.", @Model))

但是这使得模板非常难以理解,并且难以传递给营销部门以进一步设计样式。

我想补充说,使用Nuget包引用RazorEngine不是一个解决方案,因为它基于Razor 1,并且在整个过程的某个地方,system.web.razor的DLL被版本2取代,它破坏了任何使用的代码RazorEngine。使用Razor 2从新功能中受益并保持最新状态似乎更有趣。

关于如何解决这个问题的任何建议都会很棒。分享您的经验也非常受欢迎。

更新1

看起来调用SetTemplateBaseType可能有帮助,但这个方法不再存在,所以我想知道如何能够绑定templatebasetype?

//Missing method in the new RazorEngine build from coxp.
Razor.SetTemplateBaseType(typeof(HtmlTemplateBase<>));

2 个答案:

答案 0 :(得分:4)

我使用Windsor注入模板服务而不是使用Razor对象。以下是代码的简化部分,其中显示了如何设置基本模板类型。

    private static ITemplateService CreateTemplateService()
    {
        var config = new TemplateServiceConfiguration
                         {
                             BaseTemplateType = typeof (HtmlTemplateBase<>),
                         };
        return new TemplateService(config);
    }

答案 1 :(得分:0)

RazorEngine 3.1.0

基于 coxp 答案的一点点修改示例,没有注入:

    private static bool _razorInitialized;

    private static void InitializeRazor()
    {
        if (_razorInitialized) return;
        _razorInitialized = true;
        Razor.SetTemplateService(CreateTemplateService());
    }

    private static ITemplateService CreateTemplateService()
    {
        var config = new TemplateServiceConfiguration
            {
                BaseTemplateType = typeof (HtmlTemplateBase<>),
            };
        return new TemplateService(config);
    }

    public static string ParseTemplate(string name, object model)
    {
        InitializeRazor();

        var appFileName = "~/EmailTemplates/" + name + ".cshtml";
        var template = File.ReadAllText(HttpContext.Current.Server.MapPath(appFileName));
        return RazorEngine.Razor.Parse(template, model);
    }