尝试发送电子邮件时 RazorEngine 错误
RazorEngine Error trying to send email
我有一个发送多封电子邮件的 MVC 4 应用程序。比如我有一个提交订单的邮件模板,一个取消订单的模板等等...
我有一个 Email Service
有多种方法。我的控制器调用 Send
方法,如下所示:
public virtual void Send(List<string> recipients, string subject, string template, object data)
{
...
string html = GetContent(template, data);
...
}
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);
}
我收到错误消息:
The same key was already used for another template!
在我的 GetContent
方法中,我应该为 TemplateKey
添加一个新参数并使用该变量而不是总是使用 htmlTemplate
吗?那么 new order email template
可以有 newOrderKey
和 CancelOrderKey
作为用于取消订单的电子邮件模板?
说明
发生这种情况是因为您对多个不同的模板使用了相同的模板密钥 ("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!");
}
}
启动时设置:
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 的贡献者)
我有一个发送多封电子邮件的 MVC 4 应用程序。比如我有一个提交订单的邮件模板,一个取消订单的模板等等...
我有一个 Email Service
有多种方法。我的控制器调用 Send
方法,如下所示:
public virtual void Send(List<string> recipients, string subject, string template, object data)
{
...
string html = GetContent(template, data);
...
}
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);
}
我收到错误消息:
The same key was already used for another template!
在我的 GetContent
方法中,我应该为 TemplateKey
添加一个新参数并使用该变量而不是总是使用 htmlTemplate
吗?那么 new order email template
可以有 newOrderKey
和 CancelOrderKey
作为用于取消订单的电子邮件模板?
说明
发生这种情况是因为您对多个不同的模板使用了相同的模板密钥 ("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!");
}
}
启动时设置:
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 的贡献者)