尝试发送电子邮件的RazorEngine错误 [英] RazorEngine Error trying to send email
问题描述
我有一个MVC 4应用程序,可以发送多封电子邮件.例如,我有一个用于提交订单的电子邮件模板,一个用于取消订单的模板等...
I have an MVC 4 application that sends out multiple emails. For example, I have an email template for submitting an order, a template for cancelling an order, etc...
我有一个具有多种方法的Email Service
.我的控制器调用了如下所示的Send
方法:
I have an Email Service
with multiple methods. My controller calls the Send
method which looks like this:
public virtual void Send(List<string> recipients, string subject, string template, object data)
{
...
string html = GetContent(template, data);
...
}
Send
方法调用GetContent
,这是导致问题的方法:
The Send
method calls GetContent
, which is the method causing the problem:
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);
}
我收到错误:
同一密钥已经用于另一个模板!
The same key was already used for another template!
在我的GetContent
方法中,我应该为TemplateKey
添加一个新参数并使用该变量而不是始终使用htmlTemplate
吗?那么new order email template
可以使用newOrderKey
和CancelOrderKey
作为用于取消订单的电子邮件模板吗?
In my GetContent
method should I add a new parameter for the TemplateKey
and use that variable instead of always using htmlTemplate
? Then the new order email template
could have newOrderKey
and CancelOrderKey
for the email template being used to cancel an order?
推荐答案
说明
之所以会发生这种情况,是因为您对多个不同的模板使用了相同的模板密钥("htmlTemplate"
).
请注意,您当前实现GetContent
的方式将遇到多个问题:
Explanation
This happens because you use the same template key ("htmlTemplate"
) for multiple different templates.
Note that the way you currently have implemented GetContent
you will run into multiple problems:
-
即使使用唯一键(例如
template
变量),在磁盘上编辑模板时也会触发异常.
Even if you use a unique key, for example the
template
variable, you will trigger the exception when the templates are edited on disk.
性能:即使模板已经被缓存,您每次都在读取模板文件.
Performance: You are reading the template file every time even when the template is already cached.
实施 ITemplateManager
界面来管理模板:
Implement the ITemplateManager
interface to manage your templates:
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!");
}
}
启动时设置:
var config = new TemplateServiceConfiguration();
config.Debug = true;
config.TemplateManager = new MyTemplateManager(BaseTemplatePath);
Engine.Razor = RazorEngineService.Create(config);
并使用它:
// You don't really need this method anymore.
private string GetContent(string template, object data)
{
return Engine.Razor.RunCompile(template, null, data);
}
RazorEngine现在将在内部修复上述所有问题.请注意,最好使用模板名称作为键,如果在您的方案中,只需要名称来标识模板(否则就不能使用NameOnlyTemplateKey
,而需要提供自己的实现).
RazorEngine will now fix all the problems mentioned above internally. Notice how it is perfectly fine to use the name of the template as key, if in your scenario the name is all you need to identify a template (otherwise you cannot use NameOnlyTemplateKey
and need to provide your own implementation).
希望这会有所帮助. (免责声明:RazorEngine的贡献者)
Hope this helps. (Disclaimer: Contributor of RazorEngine)
这篇关于尝试发送电子邮件的RazorEngine错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!