Asp.net-Mvc-4

嘗試發送電子郵件時出現 RazorEngine 錯誤

  • April 22, 2015

我有一個發送多封電子郵件的 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);
}

我收到錯誤:

相同的密鑰已用於另一個模板!

在我的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 的貢獻者)

引用自:https://stackoverflow.com/questions/29803561