最近项目中需要实现发送邮件+添加附件的功能,于是又学习了一下System.Net.Mail.MailMessage和System.Net.Mail.SmtpClient等几个.Net中发邮件的几个类,根据网上的一些代码,做了一个小Demo分享一下。
界面效果
老规矩,还是先看效果,以下为发送邮件的界面:
发件人输入发送人的邮箱、密码;
收件人栏目可输入多个收件人,多个收件人之间需要用英文状态下的分号“ ; ”来隔开(当然这只是一种方式,还可以根据需求设计输入联系人的方式,如从通讯录选择联系人等);
主题、内容不再多说,附件可选择多个附件,这里只画了三个input控件,也可以根据需求增删控件或动态设置控件数量。
代码
下面来看代码,根据代码整理思路:
这是这个小Demo的解决方案结构:
根目录建立了一个files文件夹,作为客户端发送邮件时在服务端的一个临时目录(这里如果不明白,请继续往下看)。
界面代码:
Default.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="SendEmail_Attachments.Default" %> <!DOCTYPE html> <html> <head runat="server"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title></title> </head> <body> <form id="form1" runat="server"> <div> <table align="center" border="0" cellpadding="0" cellspacing="0" width="776"> <tr> <td> <table align="center" border="0" cellpadding="4" cellspacing="1" width="600" bgcolor="#cccccc"> <tr> <td colspan="2" bgcolor="#f0f0f0" align="center">发送邮件+多收件人+多附件</td> </tr> <tr> <td bgcolor="#f0f0f0" align="right" style="width: 73px">发送人:</td> <td bgcolor="#ffffff" align="left"> <asp:TextBox ID="fromMail" runat="server" Width="300" /></td> </tr> <tr> <td bgcolor="#f0f0f0" align="right" style="width: 73px">密 码:</td> <td bgcolor="#ffffff" align="left"> <asp:TextBox ID="password" runat="server" Width="300" TextMode="Password"/></td> </tr> <tr> <td bgcolor="#f0f0f0" align="right" style="width: 73px; height: 32px">收件人:</td> <td bgcolor="#ffffff" align="left" style="height: 32px"> <asp:TextBox ID="toMail" runat="server" TextMode="multiLine" Width="300px" Height="22"/><asp:Label ID="Label1" runat="server" Text="多个收件人请用分号隔开" ForeColor="Red"></asp:Label></td> </tr> <tr> <td bgcolor="#f0f0f0" align="right" style="width: 73px">主 题:</td> <td bgcolor="#ffffff" align="left"> <asp:TextBox ID="subject" runat="server" Width="300" /></td> </tr> <tr> <td bgcolor="#f0f0f0" align="center" style="width: 74px">附 件:</td> <td bgcolor="#ffffff" align="left"> <input type="file" id="upfile1" runat="server" style="width: 297px"/> <input type="file" id="upfile2" runat="server" style="width: 297px"/> <input type="file" id="upfile3" runat="server" style="width: 297px"/> </td> </tr> <tr> <td bgcolor="#f0f0f0" align="right" style="width: 73px">内 容:</td> <td bgcolor="#ffffff" align="left"> <asp:TextBox ID="body" TextMode="multiLine" runat="server" Width="500px" Height="200" /></td> </tr> <tr> <td bgcolor="#f0f0f0" align="right" style="width: 73px">格 式:</td> <td bgcolor="#ffffff" align="left"> <asp:RadioButtonList ID="format" runat="server" /></td> </tr> <tr> <td bgcolor="#f0f0f0" colspan="2" align="center"> <asp:Button ID="send" runat="server" Text="发送" OnClick="send_Click" /> <asp:Button ID="reset" runat="server" Text="重置" /> </td> </tr> </table> </td> </tr> </table> </div> </form> </body> </html>
界面代码比较简单,这里不再多说。
服务端代码:
Default.aspx.cs
注意引用相应的命名空间
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.Net.Mail; using System.Text; using System.Net; using System.IO; namespace SendEmail_Attachments { public partial class Default : System.Web.UI.Page { //ASP.NET发送邮件带附件 http://blog.csdn.net/hope94/article/details/4364471 protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { format.Items.Add(new ListItem("文本", "0")); format.Items.Add(new ListItem("HTML", "1")); format.Items[0].Selected = true; } } /// <summary> /// 发送邮件的点击事件 /// </summary> /// <param name="obj"></param> /// <param name="e"></param> protected void send_Click(object obj, EventArgs e) { bool flag = SendMail(); if (flag == true) { Page.ClientScript.RegisterStartupScript(Page.GetType(), "message", "<script language='javascript' defer>alert('发送成功!');</script>"); } else { Page.ClientScript.RegisterStartupScript(Page.GetType(), "message", "<script language='javascript' defer>alert('发送失败!');</script>"); } } /// <summary> /// 发送邮件的执行过程 /// </summary> /// <returns></returns> public bool SendMail() { //实例化MailMessage类,该类表示可以使用 SmtpClient 类发送的电子邮件 //这里myEmail就表示将要发送的电子邮件实例 MailMessage myEmail = new MailMessage(); myEmail.From = new MailAddress(fromMail.Text.Trim()); //电子邮件的发件人 myEmail.Subject = subject.Text.Trim(); //电子邮件的主题 myEmail.IsBodyHtml = format.SelectedItem.Value == "0" ? false : true; //设置电子邮件正文格式是否为HTML格式 //遍历收件人邮箱地址,并添加到此邮件的收件人里 if (toMail.Text.Trim().Length != 0) { string[] receivers = toMail.Text.Trim().Split(';'); for (int i = 0; i < receivers.Length; i++) { if (receivers[i].Length > 0) { myEmail.To.Add(receivers[i]); //为该电子邮件添加联系人 } } } //遍历从客户端接收到的附件,并依次添加到邮件的附件中 HttpFileCollection uploadFilCol = Request.Files; for (int i = 0; i < uploadFilCol.Count; i++) { string ServerFileName = ""; HttpPostedFile file = uploadFilCol[i]; if (file.ContentLength != 0) { try { string upFileName = file.FileName; string[] strTemp = upFileName.Split('.'); string upFileExp = strTemp[strTemp.Length - 1].ToString(); string fileName = upFileName.Substring(upFileName.LastIndexOf("\\") + 1); ServerFileName = Server.MapPath("/files") + "\\" + fileName; file.SaveAs(ServerFileName); //将此文件临时保存到服务端的files目录 myEmail.Attachments.Add(new Attachment(ServerFileName)); //为该电子邮件添加附件 } catch (Exception ex) { Page.ClientScript.RegisterStartupScript(Page.GetType(), "message", "<script language='javascript' defer>alert(" + ex.Message + ");</script>"); throw; } } } myEmail.Body = body.Text.Trim(); //电子邮件的主体内容 myEmail.BodyEncoding = Encoding.UTF8; //电子邮件主体内容的编码方式 myEmail.Priority = MailPriority.High; //设置此电子邮件的优先级 //实例化SmtpClient类,该类用于将电子邮件发送到 SMTP 服务器以便传递 SmtpClient smtp = new SmtpClient(); smtp.Credentials = new NetworkCredential(fromMail.Text.Trim(), password.Text.Trim()); //设置用于验证发件人身份的凭据 smtp.Port = 25; //设置用于 SMTP 事务的端口 //根据发件人的电子邮件地址判断发件服务器地址 if (fromMail.Text.Trim().Length != 0) { string[] addressor = fromMail.Text.Trim().Split(new Char[] { '@', '.' }); switch (addressor[1]) { case "163": smtp.Host = "smtp.163.com"; break; case "gmail": smtp.Host = "smtp.gmail.com"; break; case "hotmail": smtp.Host = "smtp-mail.outlook.com"; break; case "qq": smtp.Host = "smtp.qq.com"; break; case "foxmail": smtp.Host = "smtp.qq.com"; break; case "sina": smtp.Host = "smtp.sina.com.cn"; break; } } smtp.EnableSsl = true; //指定 SmtpClient 是否使用安全套接字层(SSL)加密连接 try { smtp.Send(myEmail); //发送该邮件 myEmail.Dispose(); //关闭邮件使用的所有进程 DeleteFiles(); //删除临时目录files中刚刚上传的所有附件 } catch (Exception e) { DeleteFiles(); //删除临时目录files中刚刚上传的所有附件 Page.ClientScript.RegisterStartupScript(Page.GetType(), "message", "<script language='javascript' defer>alert('发送失败,请检查您的邮箱账号和密码是否填写正确!');</script>"); ; } return true; } /// <summary> /// 遍历删除files文件夹内所有刚刚上传的附件 /// </summary> protected void DeleteFiles() { DirectoryInfo files = new DirectoryInfo(Server.MapPath("/files")); foreach (System.IO.FileInfo f in files.GetFiles("*.*")) { f.Delete(); } } } }
这里主要用到两个类,System.Net.Mail.MailMessage和System.Net.Mail.SmtpClient,简单来说,MailMessage就是我们要发的邮件,SmtpClient的功能是在一定条件下把该邮件发送出去。
System.Net.Mail.MailMessage类
在MSDN上可以查到,MailMessage的属性如下:
其中收件人To属性、抄送CC、密送BCC和附件Attachments都可以为多个值,所以在上面代码中,在发送函数SendEmail()中才可以为邮件添加多个收件人和多个附件,这里没有添加密送和抄送的功能,但道理一样。
System.Net.Mail.SmtpClient类
SmtpClient的属性有:
方法有:
根据这些属性和方法,您肯定能够理解代码中SmtpClient是如何将电子邮件发送出去了,这里说明几点注意事项:
SmtpClient的Host属性,发送不同类型的电子邮件使用的服务器是不同的,因此Host属性也是不同的,如果您有多个种类的邮箱,那么可以看一下您每个邮箱的发件服务器的地址是不是不同的,比如:
163邮箱的发件服务器地址为:smtp.163.com
谷歌邮箱的发件服务器地址为:smtp.gmail.com
Hotmail邮箱的发件服务器地址为:smtp-mail.outlook.com
Foxmail和QQ邮箱的发件服务器地址为:smtp.qq.com
所以在代码中,加了一个Switch来根据发件人邮箱类型来设置发件服务器地址~∪~
最后邮件发送成功或者失败时,都需要调用一下DeleteFiles()函数,来删除刚刚上传到服务器上的临时文件(附件),说一下为什么要增加这个files文件夹,因为这个例子在一台电脑上做测试完全不必加这个文件夹,直接把本地文件作为附件添加到MailMessage的实例就行,但因为为MailMessage添加附件这句代码myEmail.Attachments.Add(new Attachment(ServerFileName)); 是运行在服务端的,因此如果程序发布,在异地执行操作时就不可行了,所以需要先把附件上传到服务端(这里就在服务端添加了files文件夹用来存放临时文件),再为MailMessage添加该附件,最后清理上传到客户端的附件。
暂时先做成这样,后面有需求时再进行优化。