2011-07-24 9 views
7

私はサインアップ手順中に複数の電子メールをユーザーに送信するasp.net Webアプリケーションを持っています。今はコードにインラインでリンクしていますが、私はそれらをVSに行かずに編集できる中央の場所に置いておきたいと思います。電子メールテンプレートを格納する場所

これらのHTMLテンプレートを保存するのに最適な場所/フォーマットは何でしょうか?

答えて

13

ASP.NET MVCレイザーはを見て、私は簡単に任意のプロジェクトから参照できる光アセンブリで埋め込みリソースとして、私は私のウェブアプリのためのすべての私の電子メールテンプレートを保存します。

テンプレートは、この(ローカライズに気づく)のようになります。

@model Milkshake.Commerce.Model.Users.UserDto 
@using Milkshake.Core.Internationalization; 
@using Milkshake.Commerce.Model.Meta; 

@if (Language.CurrentForInterface.TwoLetterISOLanguageName.Equals("da")) 
{ 

<h1>Hej @Model.FirstName</h1> 

<p> 
    Din nye brugerkonto til Milkshake Commerce er blevet oprettet. 
</p> 

<p> 
    Gå til dine <a href="http://@ShopSettings.Instance.Domain.TrimEnd('/')/Account">konto indstillinger</a>, brug din e-mail adresse som adgangskode og du vil blive videreført til dine konto indstillinger, hvor du kan ændre din adgangskode. 
</p> 

<p>Ha' en god dag!</p> 
<h2>The Milkshake Commerce Team!</h2> 

} 
else 
{ 

<h1>Hi @Model.FirstName</h1> 

<p> 
    Your new user account for Milkshake Commerce has been created for you. 
</p> 

<p> 
    Go to your <a href="http://@ShopSettings.Instance.Domain.TrimEnd('/')/Account">user account page</a>, use your e-mail address as password and you'll be taken directly to your account page where you can change your password. 
</p> 

<p>Have a nice day!</p> 
<h2>The Milkshake Commerce Team!</h2> 

} 

それから私は "マスター" テンプレートを持っている、_AppEmailTemplate.cshtmlと呼ばれる:

@using Milkshake.Commerce.Model.Resources 

<!DOCTYPE html PUBLIC -//W3C//DTD XHTML 1.0 Transitional//EN http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd> 

<html xmlns="http://www.w3.org/1999/xhtml"> 

    <head> 
     <title></title> 

     <style type="text/css"> 
      body 
      { 
       font-family: Arial, Helvetica; 
      } 
      .layout-wrapper 
      { 
       width: 600px; 
      } 
      .header 
      { 
       background-color: #242225; 
      } 
      .header img 
      { 
       display: block; 
      } 
      .content 
      { 
       background-color: #ffffff; padding: 10px 20px; border: 10px solid #eaeaea; border-top: none; 
      } 
      .footer 
      { 
       padding: 20px; padding-top: 5px; font-size: 10px; color: #cccccc; 
      } 
      p 
      { 
       font-size: 14px; 
      } 
      p.company-details 
      { 
       font-size: 12px; 
      } 
      h1 
      { 
       font-size: 20px; 
      } 
      h2 
      { 
       font-size: 16px; 
      } 
     </style> 
     <style type="text/css" id="mobile"> 
      @@media only screen and (max-device-width: 480px) { 
       body 
       { 
       } 
       .layout-wrapper 
       { 
        width: 480px !important; 
       } 
       .header 
       { 
        background-color: transparent !important; 
       } 
       .header img 
       { 
        width: 480px !important; 
       } 
       .content 
       { 
        border: none !important; 
       } 
       .footer 
       { 
        padding-top: 15px !important; 
       } 
       p 
       { 
        font-size: 22px !important; 
       } 
       h1 
       { 
        font-size: 28px !important; 
       } 
       h2 
       { 
        font-size: 24px !important; 
       } 
      } 
     </style> 
    </head> 

    <body leftmargin="0" marginwidth="0" topmargin="0" marginheight="0" offset="0" bgcolor="#f1f1f1"> 

     <table width="100%" cellpadding="0" cellspacing="0" bgcolor="#f1f1f1"> 
      <tr> 
       <td valign="top" align="center"> 

        <table cellpadding="0" cellspacing="0" width="100%" height="80"> 
         <tr> 
          <td class="header" align="center"> 
           <table cellpadding="0" cellspacing="0" width="600" height="80" class="layout-wrapper" style="width: 600px;"> 
            <tr> 
             <td> 
              <img src="http://example.com/email-header.png" alt="Milkshake Commerce" /> 
             </td> 
            </tr> 
           </table> 
          </td> 
         </tr> 
        </table> 

        <table cellpadding="0" cellspacing="0" width="600" class="layout-wrapper"> 
         <tr> 
          <td class="content" align="left"> 
           #¤#¤CONTENTSECTION#¤#¤ 
          </td> 
         </tr> 
         <tr> 
          <td class="footer" align="left"> 
           <p>@Text.appEmailDisclaimer</p> 
           <p>@Text.appEmailFooterAd.UrlDecode()</p> 
           <p class="company-details"><i>Company name etc.</i></p> 
          </td> 
         </tr> 
        </table> 

       </td> 
      </tr> 
     </table> 

    </body> 

</html> 

実際に電子メールを送信するために、私はレンダリングのためにRazorEngineを使用してください:

public void SendSystemEmail<T>(string templateName, string subject, string fromName, string recipientEmail, T model) 
{ 
    dynamic template = this.GetEmailTemplate(templateName); 
    string layoutBody = RazorEngine.Razor.Parse(template.Layout as string, model); 
    string emailBody = RazorEngine.Razor.Parse(template.Template as string, model); 

    emailBody = layoutBody.Replace(CONTENTSECTIONREPLACETOKEN, emailBody); 

    PreMailer.Net.PreMailer pm = new PreMailer.Net.PreMailer(); 
    emailBody = pm.MoveCssInline(emailBody, true); 

    EmailDto email = new EmailDto(); 
    email.Body = emailBody; 
    email.IsBodyHtml = true; 
    email.FromEmail = "[email protected]"; 
    email.ReplyToEmail = email.FromEmail; 
    email.FromName = fromName; 
    email.RecipientEmail = recipientEmail; 
    email.Subject = subject; 
    email.Type = EmailTypes.Transactional; 

    if (String.IsNullOrWhiteSpace(email.FromName)) 
    { 
     email.FromName = "Milkshake Software"; 
    } 

    this.SendMailMessages(new List<EmailDto>() { email }, false); 
} 

上記のコードでは、私自身のEmailDto objec t。ここで簡単に[MailMessage][2]インスタンスを作成し、[SmtpClient][3]を使用して送信することができます。

また、すべての電子メールクライアントで最高のレンダリングを得るために、自分のPreMailer.Netライブラリを使用して、すべてのCSSインラインを移動します。詳細は、my blog post hereを参照してください。

(コードはGitHubの上で)GetEmailTemplateがこのん:

/// <summary> 
/// Gets the email template. 
/// </summary> 
/// <param name="templateName">Name of the template.</param> 
/// <returns>Returns the e-mail template.</returns> 
private dynamic GetEmailTemplate(string templateName) 
{ 
    string masterTemplateContents = this.GetTemplateFileContents("_AppEmailTemplate.cshtml"); 
    string templateContents = this.GetTemplateFileContents(templateName + ".html.cshtml"); 

    return new { Layout = masterTemplateContents, Template = templateContents }; 
} 

/// <summary> 
/// Gets the template file contents. 
/// </summary> 
/// <param name="templateFileName">The name of the template file.</param> 
/// <returns>Returns the contents of the template file.</returns> 
private string GetTemplateFileContents(string templateFileName) 
{ 
    return this.GetEmailFileContents("Templates", templateFileName); 
} 

/// <summary> 
/// Gets the email file contents. 
/// </summary> 
/// <param name="lastNamespaceToken">The last namespace token.</param> 
/// <param name="templateFileName">The name of the template file.</param> 
/// <returns> 
/// Returns the contents of the template file. 
/// </returns> 
private string GetEmailFileContents(string lastNamespaceToken, string templateFileName) 
{ 
    var assembly = Assembly.GetExecutingAssembly(); 

    if (assembly != null) 
    { 
     StringBuilder sb = new StringBuilder(); 

     using (StreamReader sr = new StreamReader(assembly.GetManifestResourceStream(String.Format("MyApp.BusinessLogic.Communication.{0}.{1}", lastNamespaceToken, templateFileName)))) 
     { 
      while (!sr.EndOfStream) 
      { 
       var line = sr.ReadLine(); 

       if (!line.StartsWith("@model")) 
       { 
        sb.AppendLine(line); 
       } 
      } 
     } 

     return sb.ToString(); 
    } 

    return null; 
} 
0

テンプレートの変更頻度と変更先によって異なります。例えば:アプリケーションのユーザーによって変更さ

、変更が緊急かつ潜在的に頻繁にされています。おそらく最高のデータベースに格納された電子メールが送信されるたびにロード

  • 。開発者(つまりあなた)によって変更さ

、変更がurgenまれとされない:Webサーバ上の

  • テキストファイル、キャッシュにロードし、そこにそれらを保存し、キャッシュが低下したりする場合にのみ、それらをリロードアプリケーションが再起動します。
0

.html fileにメールテンプレートを保存できます。次に、含めるパラメータをサポートするようにフォーマットします。例えば

<head> 
<title></title> 
</head> 
<body> 
    Hello <!--Name--> , 
    This is a test template 
    User Name: <!--UserName--> 
    ............................. 
    ............................. 
</body> 
</html> 

ユーザーに電子メールを送信するたびに、テンプレートをユーザー固有のものに設定して、実行時にパラメータを置き換えることができます。

1

メールテンプレートをXMLファイルに保存することをお勧めします。XMLファイルに属性を追加することでスケーラビリティを将来的に可能にし、簡単に編集できるようにします。

+0

ウェブサイトでXMLファイルを使用していて、電子メールテンプレートでサポートされている機能を大幅に拡張することができました。 –

0

、彼らが扱っているかについての洞察を与えてありがとうございました。私はここからたくさんの知識を集めました。私はデータの具体的なモデルとレイザーパーサーを使用して@MartinHNが好きです。

しかし、それは私にとって非常にうまくいきませんでした。

要件:

  • 私はいつでも
    ステークホルダーに同じことを表示することができるような電子メールテンプレートを保存する必要があります。従って、 イントラネットを介して閲覧することが可能であるべきであり、好ましくはsaeウェブサイトを介してAPIをホストする。

  • フロントエンドの設計者は、テンプレートを簡単に修正できるはずです。 したがって、デザイナーは が技術的な詳細を行き過ぎる必要がないようにプレーンHTML形式で保存したいと考えています。

  • メールテンプレートは、 管理者(将来の必要条件)の変更に簡単に利用できるようにする必要があります。近い将来、SMS、Screenの異なる通知が になります。したがって、テンプレートは異なる です。これらの要件に基づいて

、私は次のようでした:

  1. 私はMVCを使用していたので、私が直接閲覧することが可能な(およびMVCエンジン ある「STATIC」というフォルダを作成しました/ httpハンドラ このフォルダからMVCアクティビティを除外します)。このアプローチで

    ので、それはへ デザイナーのために簡単だった、私は簡単に最初の要件を達成できると私 は、各電子メールテンプレートは、独自のHTMLを与えている http://api.aksdfjl.com/static/welcomeemailtemplate.html

  2. として利害関係者への私のリンクを送信することができます同じものにアクセスして、そのリポジトリを自分のリポジトリフォルダへのショートカットとして として参照してください。 HTMLにはインラインCSSがあり、 完全に独立したHTMLです。

  3. 最後に主な要件はこれらのデザインを維持することであり、ユーザーは同じものを変更できます。さて、間違いなく、私はファイルシステムを全く扱いたくありません。私がやったことは、これらの通知がデータベースに格納され、一度それらを初期化することです。その後、管理者パネルにはwysiwyg htmlエディタが用意されています。このエディタを使用すると、プレビューや送信先を制御できます。

は今、私は私の会社は、SMS通知を、このようなEメール、スクリーンなど、さまざまなモードのためのさまざまな通知を導入して以来、将来の要件を容易に取り扱うとされていることを確認したかったです。私は、これらの答えを保存するテンプレートイニシャライザXMLの助けを借りてソフトウェア設計を拡張することに決めました。

すべてのテンプレートの母親は - MessageTemplatesと呼ばれています。xmlには、異なるタイプのテンプレート、つまりemail、sms、screenなどを初期化するために必要な情報が格納されています。ここで

enter image description here

コードは、今どのように見えるかです。

[HttpGet] 
     [Route("applications/initializenotificationtemplate")] 
     public IHttpActionResult InitializeNotificationTemplate() 
     { 
      return 
       InitializeNotificationTemplate(Path.Combine(HostingEnvironment.ApplicationPhysicalPath, 
        @"Static\InitializeData\MessageTemplates.xml")); 
     } 




[NonAction] 
     public IHttpActionResult InitializeMailTemplate(string filePath) 
     { 
      try 
      { 
       _applicationService.InitializeTemplate(filePath); 
       return Ok("Application Notification templates are initialized."); 
      } 
      catch (Exception ex) 
      { 
       return InternalServerError(ex); 
      } 
     } 

_applicationService.InitializeTemplateの定義は、次のとおりです

public bool InitializeTemplate(string filePath) 
     { 
      if (string.IsNullOrEmpty(filePath)) 
      { 
       throw new ArgumentNullException("File Path"); 
      } 

      if (!File.Exists(filePath)) 
      { 
       throw new FileNotFoundException(filePath); 
      } 


      var data = _notificationTemplateService.Get(); 
      var exceptionMessages = string.Empty; 

      if (data != null) 
      { 
       var historicalTemplates = data.ToList(); 
       historicalTemplates.ForEach((d) => _notificationTemplateService.Delete(d, out exceptionMessages)); 
      } 

      XDocument xmlDocument = XDocument.Load(filePath); 
      IEnumerable<NotificationTemplate> templates = (from template in xmlDocument.Descendants("Template") 
                  select new NotificationTemplate() 
                  { 
                   Title = template.Element("Subject").Value, 
                   Description = template.Element("Body").Value, 
                   Type = (NotificationTypeOptions)Enum.Parse(typeof(NotificationTypeOptions), template.Element("Type").Value, true), 
                   Category = (NotificationCategoryOptions)Enum.Parse(typeof(NotificationCategoryOptions), template.Attribute("category").Value, true), 
                  }).ToList(); 

      foreach (var t in templates) 
      { 
       var path = Path.Combine(Path.GetDirectoryName(filePath), Regex.Replace(t.Description, @"\t|\n|\r| ", "")); 
       if (File.Exists(path)) 
       { 
        StreamReader reader = new StreamReader(path); 
        t.Description = reader.ReadToEnd(); 
       } 
       else 
       { 
        t.Description = string.Empty; 
       } 
      } 

      return _notificationTemplateService.InsertRange(templates, out exceptionMessages); 
     } 

これはつまり、データベースモデル(最初のコード - EFのアプローチ)と同じであるように私のモデルがどのように見えるかです。私は自分のアプリケーションをインストールするときに、非常に最初の時間については

public class NotificationTemplate : IdentityBase 
    { 
     public string Category { get; set; } 
     public NotificationTypeOptions Type { get; set; } 
     public string Title { get; set; } 
     public string Description { get; set; } 

     public NotificationTemplate() 
     { 
      Type = NotificationTypeOptions.Email; 
     } 
    } 

[Flags] 
    public enum NotificationTypeOptions 
    { 
     Email = 0, 
     Screen = 1, 
    } 

は、私はデータベースに私の通知テンプレートをインストールし、他のすべてのオプションが利用でき、使用する準備ができているAPI呼び出しを初期化する呼び出します。

このアプローチでは、私は組織内で皆を幸せにしました。これをさらに拡張して新しいテンプレートを導入するのは簡単です。

関連する問題