RazorEngine尝试发送电子邮件时出错

And*_*rew 9 asp.net-mvc-4 razorengine

我有一个发送多封电子邮件的MVC 4应用程序.例如,我有一个用于提交订单的电子邮件模板,一个用于取消订单的模板等...

我有Email Service多种方法.我的控制器调用如下所示的Send方法:

public virtual void Send(List<string> recipients, string subject, string template, object data)
{
    ...
    string html = GetContent(template, data);
    ...
}
Run Code Online (Sandbox Code Playgroud)

Send方法调用GetContent,这是导致该问题的方法:

private string GetContent(string template, object data)
{
    string path = Path.Combine(BaseTemplatePath, string.Format("{0}{1}", template, ".html.cshtml"));
    string content = File.ReadAllText(path);
    return Engine.Razor.RunCompile(content, "htmlTemplate", null, data);
}
Run Code Online (Sandbox Code Playgroud)

我收到错误:

相同的密钥已用于另一个模板!

GetContent应该在我的方法中添加一个新参数TemplateKey并使用该变量而不是总是使用htmlTemplate?然后new order email template可以使用newOrderKeyCancelOrderKey用于取消订单的电子邮件模板?

mat*_*hid 17

说明

发生这种情况是因为您"htmlTemplate"对多个不同的模板使用相同的模板键().请注意,您当前实现的方式GetContent将遇到多个问题:

  • 即使您使用唯一键(例如template变量),也会在磁盘上编辑模板时触发异常.

  • 性能:即使模板已经缓存,您每次都在读取模板文件.

解:

实现ITemplateManager界面来管理模板:

public class MyTemplateManager : ITemplateManager
{
    private readonly string baseTemplatePath;
    public MyTemplateManager(string basePath) {
      baseTemplatePath = basePath;
    }

    public ITemplateSource Resolve(ITemplateKey key)
    {
        string template = key.Name;
        string path = Path.Combine(baseTemplatePath, string.Format("{0}{1}", template, ".html.cshtml"));
        string content = File.ReadAllText(path);
        return new LoadedTemplateSource(content, path);
    }

    public ITemplateKey GetKey(string name, ResolveType resolveType, ITemplateKey context)
    {
        return new NameOnlyTemplateKey(name, resolveType, context);
    }

    public void AddDynamic(ITemplateKey key, ITemplateSource source)
    {
        throw new NotImplementedException("dynamic templates are not supported!");
    }
}
Run Code Online (Sandbox Code Playgroud)

启动时设置:

var config = new TemplateServiceConfiguration();
config.Debug = true;
config.TemplateManager = new MyTemplateManager(BaseTemplatePath); 
Engine.Razor = RazorEngineService.Create(config);
Run Code Online (Sandbox Code Playgroud)

并使用它:

// You don't really need this method anymore.
private string GetContent(string template, object data)
{
    return Engine.Razor.RunCompile(template, null, data);
}
Run Code Online (Sandbox Code Playgroud)

RazorEngine现在将解决上面提到的所有问题.注意如何将模板的名称用作键是完全正确的,如果在您的方案中,您只需要识别模板的名称(否则您无法使用NameOnlyTemplateKey并需要提供自己的实现).

希望这可以帮助.(免责声明:RazorEngine的贡献者)

  • 这是一个很大的帮助.谢谢.我个人认为这个API过于复杂,它应该像`string content = razorEngine.Run(templateFile,model); (6认同)