实现发送邮件动态html内容的⼏种思路
需求:
⼀个B2B系统在注册⽤户申请买家,申请审批通过,订单创建,申批通过时都需要发送邮件,邮件内容需要包括⼀些⽐较正规的格式,⽽且其中会包含⽤户信息,订单信息这些动态内容。另外邮件内容以后可能会频繁调整,需要有⽐较灵活的定制化。
实现:
了解过这个需求后,⼤概想到了或到了⼏种实现:
1.通过代码构造邮件内容,对于其中的动态的内容,直接拼凑。优点是最直接,不会涉及其它的技术思考。缺点是需要繁琐的拼接代码,不容易直接看到显⽰效果,不⽅便发现问题,对后不调整的话不容易修改。
2.和上⾯的⽅法类似,但是⼀个⽂件中只指定好固定的格式,把变化的部分⽤特定的字符代替,由程序读取这个”模板“⽂件内容,⽤具体内容替换模板⽂件中的指定字符即可。优点是实现⽐较简单,固定的部分⽐较容易控制和修改,但是动态读取的内容部分⽐较难以实现和维护。由于邮件中的内容并不是简单的⼏个字符,⽽是说整个订单信息,这其中包括单头和单⾝列表,⽽且其中会有⽐较特殊的格式显⽰控制。所
以使⽤这个⽅法也不合适。
相关连接:
3.使⽤页⾯来表⽰需要发送的邮件内容,然后请求这个页⾯⽣成的Html直接作为发送内容。在这⾥可以使⽤⽤户控件代替普通的APSX⽂件,在⽤户控件的前台,我们直接象显⽰页⾯内容那样来显⽰我们的邮件内容:
这⾥只列出来代码的⼀个⽚段,邮件还包括其它的⼀些固定的内容,详细的请直接下载源代码查看,其中包括实体类的代码这⾥也就不再列出来了。在⽤户控件的后台,我们只需要添加⼀个公开的属性:
1:  public Order Order
2:        {
3:  get;
4:  set;
5:        }
然后我们需要动态加载这个⽤户控件,指定属性,再输出成Html属性即可:
1:  Order order = Tools.CreateOrder();
2:  Control mailTemplate = LoadControl("MailTemplate.ascx");
3:
4:  ((MailTemplate)mailTemplate).Order = order;
5:  StringBuilder stringBuilder = new StringBuilder();
6:  StringWriter stringWriter = new StringWriter(stringBuilder);
7:  HtmlTextWriter htmlTextWriter = new HtmlTextWriter(stringWriter);
8:  mailTemplate.RenderControl(htmlTextWriter);
9:  htmlTextWriter.Close();
10:
11:  //发送邮件
12:  MailMessage mm = new MailMessage();
13:  mm.Subject = string.Format("您的订单({0}) -- 订单已经确认", order.OrderNo);
14:  mm.IsBodyHtml = true;
15:  mm.To.Add("***********************");
16:  mm.Body = stringBuilder.ToString();
17:  Tools.SendEmail(mm);
在这⾥我们也省略发邮件的代码,运⾏,查看⼀下收到的邮件,OK.
使⽤这种⽅法应该是⽐较快捷的,相对于以上来说灵活了不少,格式容易控制,以后修改起来也⽐较⽅便。不过就是模板⽂件和代码⽂件混在⼀起。
4.使⽤模板引擎,⽐如Nvelocity,StringTemplate。因为之前接触过Nvelocity,所以尝试了使⽤Nvelocity,具体有关的配置可以参照这个⽂章    Nvelocity的模板⽂件和上⾯我们的⽅法也是相当类似的。
1:  <table border="0" cellspacing="0"
3:  cellpadding="2" width="80%">
3:  cellpadding="2" width="80%">
4:      <tbody>
5:          <tr>
6:              <td>
7:  订单号:$order.OrderNo
8:  </td>
9:              <td>
10:  客户编号:$order.CardCode
11:  </td>
12:              <td>
13:  下单⽇期:$order.CreateDate
14:  </td>
15:          </tr>
16:          <tr>
17:              <td>
18:  运费:$order.Freight
19:  </td>
20:              <td>
21:  交易币种:$order.Currencyhtml代码
22:  </td>
23:              <td>
24:
25:              </td>
26:          </tr>
27:          <tr>
28:              <td colspan="3">
29:   
30:  </td>
31:          </tr>
32:          <tr>
33:              <td colspan="3">
34:  送货地址:$order.ShipAddress
35:  </td>
36:          </tr>
37:
38:
39:          <tr>
40:          <td  colspan="3">
41:          <font  color="red">具体的交货时将将由我们的客服⼈员与您联系协商</font>
42:          </td>
43:          </tr>
44:          <tr>
45:
46:          <tr>
47:              <td colspan="3">
48:                  <br>
49:                  <table border="0" cellspacing="5" cellpadding="4" width="100%" 50:  align="center">
51:                      <tbody>
52:                          <tr>
53:                              <td>
54:                                  <strong>产品编号</strong>
55:                              </td>
56:                              <td>
57:                                  <strong>单位</strong>
58:                              </td>
59:                              <td width="60">
60:                                  <strong>数量</strong>
61:                              </td>
62:                              <td width="80">
63:                                  <strong>单价</strong>
64:                              </td>
65:                          </tr>
66:  #foreach( $item  in  $order.OrderItems)
67:  <tr>
68:                              <td>
69:  ${item.ItemCode}
70:  </td>
71:                              <td>
72:  ${item.Unit}
73:  </td>
74:                              <td>
75:  ${item.Quantity}
76:  </td>
77:                              <td>
78:  ${item.BasicPrice}
79:  </td>
80:
81:                          </tr>
82:  #end
83:  </tbody>
84:                  </table>
85:
86:              </td>
87:          </tr>
88:      </tbody>
89:  </table>
不同的是,我们的模板⽂件是单独的⼀个⽂件,⽽我们只需要加载这个模板⽂件,指定参数就可以了。
1:  public static VelocityEngine InitVelocity()
2:        {
3:  //创建NVelocity引擎的实例对象
4:  VelocityEngine velocity = new VelocityEngine();
5:  //初始化该实例对象
6:  ExtendedProperties props = new ExtendedProperties();
7:            props.AddProperty(RuntimeConstants.RESOURCE_LOADER, "file");
8:            props.AddProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, System.Web.HttpContext.Current.Server.MapPath("\\mailTemplate"));
9:            props.AddProperty(RuntimeConstants.INPUT_ENCODING, "gb2312");
10:            props.AddProperty(RuntimeConstants.OUTPUT_ENCODING, "gb2312");
11:            velocity.Init(props);
12:  return velocity;
13:        }
14:
15:  private  void SendOrderConfirmdEmail()
16:        {
17:  VelocityEngine velocity = InitVelocity();
18:  //从⽂件中读取模板
19:  Template temp = velocity.GetTemplate("CreateOrderMail.vm");
20:
21:  Order order = Tools.CreateOrder();
22:  IContext context = new VelocityContext();
23:            context.Put("order", order);
24:  //合并模板
25:  StringWriter writer = new StringWriter();
26:            temp.Merge(context, writer);
27:
28:  //发送邮件
29:  MailMessage mm = new MailMessage();
30:            mm.Subject = string.Format("您的订单({0}) -- 订单已经确认", order.OrderNo);
31:            mm.IsBodyHtml = true;
32:            mm.To.Add("***********************");
33:            mm.Body = writer.GetStringBuilder().ToString();
34:  Tools.SendEmail(mm);
35:        }
在这⾥需要注意的是上⾯的第8⾏,这⾥需要加载的是你的模板⽂件所在⽗级物理路径,我把模板⽂件放在mailTemplate⽂件夹下⾯。运⾏,我们可以看到结果和上⾯的是⼀样⼀样的。这个⽅法要求对这个模板引擎有些了解,其实还是没有啥难度的。带来了⽐较⼤的灵活性,模板⽂件可以创建⼀个功能模块,允许⽤户编辑修改,⽽不会造成编译错误。
5.使⽤通常的XML+Xsl的⽅式⽣成html,这也是很容易想到的⼀个⽅法。但是由于发送邮件的点实在太多,使⽤这种⽅法编写的难度⽐较⼤了,⽽且需要匹配每个属性,不可取。
6.搜索了⼀下有没有相关的开源项⽬,只搜索到了⼀个Email Template Framework,是通过xml⽂件来配置发送的选项和邮件的内容,但是看介绍觉得对于⽐较简单的格式应该能够实现,但是⽐较复制的夹杂着⽐较多的html的邮件内容,有可能会遇到问题,另外由于时间问题,应尽量少⽤⽐较少见的开源项⽬,避免遇到不能解决的问题。
参照:
结论:
1.通往⼀个⽬的地的途径真的很多,⼤概了解了以上⼏种⽅法之后,最后还是决定使⽤nvelocity模板的⽅式来完成这个功能,完成⼏个点的邮件发送只⽤了半个⼩时。当然,应该还有更多的⽅法,更简单的⽅法,如果您有不同的思路和想法,请在评论中分享.
2.往往在研究某个技术的本⾝,有时会在遇到具体的功能问题时,反⽽不会把技术和实现联系起来。⽽只有联系起来才能够使技术产⽣实⽤价值。
代码下载:
作者:()
出处:
本⽂版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在⽂章页⾯明显位置给出原⽂连接,否则保留追究法律责任的权利。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。