Quantcast
Channel: 黑暗執行緒
Viewing all articles
Browse latest Browse all 2311

使用 Razor 產生客製化 Email 內容

$
0
0

多年下來,寫程式發 Email 通知的需求做過 N 回,其中寄給客戶的通知為求美觀常需採用 HTML 格式,而客戶姓名、通知內容等要隨客戶動態改變,嚴格來說也是一種套表。過去我慣用一套自己發明的「特別註記+Replace」做法,例如:

var tmpl = "<span>[$Name$]</span> 您好,您的等侯順位為<span>[$SeqNo$]</span>";
var dict = new Dictionary<string, string>()
{
    ["Name"] = "Jeffrey",
    ["SeqNo"] = "007"
};
var res = System.Text.RegularExpressions.Regex.Replace(
    tmpl, @"\[\$(?<n>.+?)\$\]", m =>
    {
        var n = m.Groups["n"].Value;
return dict.ContainsKey(n) ? dict[n] : "<" + n + ">";
    });
Console.WriteLine(res);
Console.Read();

土砲做法雖然簡陋,不能 IF ELSE 也沒法跑迴圈,倒也淺顯易懂,就這麼一用十幾年 XD

最近專案又有類似需求打算重操舊業,轉念一想,一帖老方子從 VB6 寫到 C# 6 未免太不長進,該想想有沒有更好的方法。接著馬上有個念頭浮現腦海 - 寫了那麼多 ASP.NET MVC 見識過 CSHTML 的威力,既然信件內文也是 HTML,為什麼不用 Razor 來套版呢?

爬文很快找到順手的兵刃 – RazorEngine,一個允許在任何 .NET 專案(不必是 ASP.NET MVC)使用 Razor 的程式庫:

來個實例,假設我有個中獎通知函要動態改變中獎者姓名、頭銜、獎項內容與日期,若用 Razor 來寫會像這樣(MailTemplate.cshtml):

@model RazorMailTmpl.Models.MailData
 
<!DOCTYPEhtml>
 
<html>
<head>
<metacharset="utf-8"/>
<title>Razor Mail Template Demo</title>
<style>
        li { color: #0000ff; }
        .due { color: orangered; }
</style>
</head>
<body>
<p>親愛的 @Model.WinnerName @Model.Title,</p>
<p>感謝您參加部落格讀者2017年終摸彩,在此恭喜您獲得以下獎項:</p>
<ul>
    @foreach (var prize in Model.Prizes)
    {
<li>@prize</li>
    }
</ul>
<p>
請在 
<spanclass="due">@Model.DueDate.ToString("yyyy/MM/dd")</span>
前連絡謎之聲領取獎項。
</p>
<p>再次恭喜您幸運中獎!</p>
<p>Regards,<br/>黑暗執行緒部落格抽獎小組</p>
</body>
</html>

接著宣告一個 MailData 資料型別,這樣在編輯 cshtml 時才能享受強型別與 Inetllisense 提示:

using System;
 
namespace RazorMailTmpl.Models
{
publicclass MailData
    {
publicstring WinnerName { get; set; }
publicstring Title { get; set; }
publicstring[] Prizes { get; set; }
public DateTime DueDate { get; set; }
 
    }
}

要用 RazorEngine 套表很簡單,先建好 MailData 物件,使用 Engin.Razor.AddTemplate() 載入範本,引擎內建 Cache 機制,接著呼叫 Run 或 Compile 以 Cache Key 取出範本進行編譯運算,很快就能得到套表後的 HTML 字串結果:

using RazorEngine;
using RazorEngine.Templating;
using RazorMailTmpl.Models;
using System;
 
namespace RazorMailTmpl
{
class Program
    {
staticvoid Main(string[] args)
        {
            var mailData = new MailData()
            {
                WinnerName = "Jeffrey",
                DueDate = new DateTime(2018, 2, 14),
                Title = "老司機",
                Prizes = newstring[]
                {
"32G USB 行動碟一支",
"Visual Studio 2017 紀念貼紙一組",
"法拉帝(Ferretti) 660 豪華遊艇(20米)一艘"
                }
            };
//將Template存入Cache以利重複使用
            Engine.Razor.AddTemplate(
"MailBody", // Cache Key
                System.IO.File.ReadAllText("MailTemplate.cshtml"));
//傳入Cache Key、Model物件型別、Model物件取得套表結果
            var result = 
                Engine.Razor.RunCompile("MailBody", typeof(MailData), mailData);
 
//除了RunCompile,也可Compile一次,Run多次以提高效能
            Engine.Razor.Compile("MailBody", typeof(MailData));
            Engine.Razor.Run("MailBody", typeof(MailData), mailData);
 
            System.IO.File.WriteAllText("Result.html", result);
        }
    }
}

薑!薑!薑!薑~ 完成。

官方文件的說明挺詳細,相信有 MVC cshtml 經驗的同學很快就能上手,祝大家套表愉快。


Viewing all articles
Browse latest Browse all 2311

Trending Articles