作为一名.Net开发,"邮件发送"功能的开发和使用是必须要掌握的,因为这个功能作为“消息推送”的一种手段经常出现在各种.Net系统中,所以本文将对.Net平台下的“邮件发送”,做一个细致的分析!
一、who需要邮件功能
1、服务提供方:需提供邮件收发客户端或Web服务。如:QQ邮箱、GMail邮箱、126、163等知名邮件服务提供商。注:如果你使用的第三方不知名邮件服务商提供的邮件收发服务,通过其发出的邮件,可能会被其他知名邮件服务提供商的STMP服务器视为是"恶意邮件或垃圾邮件"!
2、消息推送:消息推送方
3、App:某些网站会员的注册功能或者功能激活功能。
等等....
二、邮件协议
1、SMTP(Simple Mail Transfer Protocol) ---简单邮件传输协议
它是一组用于源地址到目的地址传送邮件的规则,由它来控制信件的中转方式SMTP协议属于TCP/IP协议簇,它帮助每台计算机在发送或者中转信件时找到下一个地址。通过SMTP协议指定的服务器地址,就可以把E-Mail寄到指定的收件人的服务器上了.整个过程只需要几分钟.它使用由TCP提供的可靠的数据传输服务把邮件消息从发信人的邮件服务器传送到收信人的邮件服务器。
注:SMTP服务器是遵循SMTP协议的发送邮件,用来发送或者中转发出的邮件。
详细请参考百度百科
2、POP3(Post Office Protocol -Version3) ---邮局协议第三个版本
它是TCP/IP协议中的一员,由RFC1939 定义,这个协议主要支持客户端远程管理在服务器上的电子邮件。注:提供了SSL加密的POP3协议被称为POP3S.
注:POP协议支持"离线"邮件处理。其具体过程是:邮件发送到服务器上,电子邮件客户端调用邮件客户程序用来连接服务端,并下载所有未阅读的电子邮件。这种离线模式称为存储转发模式,将邮件从服务器从邮件服务器送到个人终端上,一般是PC机或者MAC,一旦邮件发送到PC或者MAC上,存储在服务器上的邮件会立刻被删除,但目前的POP3邮件服务器都可以"只下载邮件,服务器端并不删除.",也就是改进的POP3协议.OP适用于C/S结构的脱机模型的电子邮件协议,目前已发展POP3到第三版,称POP3。脱机模型即不能在线操作,POP不支持对服务器邮件进行扩展操作,此过程需要更高级的IMAP4协议来完成。支持POP协议使用ASCII码来传输数据消息,这些数据消息可以是指令,也可以是应答。
详细请参考百度百科
3、IMAP4(Internet Message Acess Protocol -Version4) ---交互式数据消息访问协议第四个版本
IMAP协议是由斯坦福大学的Mark Crispin教授在1986年开发的,后期版本是华盛顿州立大学进行开发的,IMAP4是TCP/IP协议族中的一员,现在的版本是“IMAP第四版第一次修订版”(IMAP4rev1)。IMAP4协议与POP3协议一样也是规定个人计算机如何访问网上的邮件的服务器进行收发邮件的协议,但是IMAP4协议同POP3协议相比更高级。IMAP4支持协议客户机在线或者离开访问并阅读服务器上的邮件,还能交互式的操作服务器上的邮件。IMAP4协议更人性化的地方是不需要像POP3协议那样把邮件下载到本地,用户可以通过客户端直接对服务器上的邮件进行操作(这里的操作是指:在线阅读邮件 在线查看邮件主题 大小 发件地址等信息)。用户还可以在服务器上维护自己邮件目录(维护是指移动)新建 删除重命名共享 抓取文本 等操作)。IMAP4协议弥补了POP3协议的很多缺陷,,由RFC3501定义。本协议是用于客户机远程访问服务器上电子邮件,它是邮件传输协议新的标准。
详细请参考百度百科
三、邮箱分类
现阶段的邮箱主要有以下几种:免费邮箱、vip邮箱、域名邮箱、企业邮箱.......。
1、免费邮箱
“免费邮箱”是邮件商家为任何人免费提供的电子邮件传输服务,作为交换,该网站上你请求电子邮件服务和一些个人信息的地方会显示广告。它更适合个人生活和娱乐的需要,却并非那么注重邮箱的安全和功能。
部分免费邮件SMTP服务器参考设置:
Email类型 |
SMTP[Host]主服务器 |
Port[端口号] |
是否可启用SSL |
Gmail(Google 的网络邮件服务) |
smtp.gmail.com |
587 |
True |
HotMail/Live |
smtp.live.com |
25 |
True |
QQ/FoxMail(Foxmail被腾讯收购) |
smtp.qq.com |
25 |
False |
smtp.126.com |
25 |
False |
|
smtp.163.com |
25 |
False |
|
Sina(新浪邮箱) |
smtp.sina.com |
25 |
False |
Tom |
smtp.tom.com |
25 |
False |
SoHu(搜狐邮箱) |
smtp.sohu.com |
25 |
False |
smtp.mail.yahoo.com |
25 |
False |
2、vip邮箱
“vip邮箱”即邮件商家提供的收费版邮件服务,在速度、安全、稳定性、容量、附件大小限制、群发数等方面相对好些。其SMTP服务器设置就是多了个vip字符。eg:smtp.vip.qq.com。邮箱地址:369220123@vip.qq.com。
3、域名邮箱
“域名邮箱”是个性化邮件服务,能让您用自己的域名做为后缀即“@自己的域名”,前提是你需要一个域名(通常域名要收费)。功能比免费邮箱要多:可分配单个邮箱、规划容量、更加的安全、更好的稳定性、个性化名称、邮件发送量更大、附件大小限制等等。
4、企业邮箱
“企业邮箱”是域名邮箱,但通常是指通过付费方式获得更好服务的邮箱。eg:您公司域名为www.abc.com,则SMTP服务器为:mail.abc.com,邮箱地址:office@abc.com;
使用企业邮箱的优势:
1) 提升公司企业形象、邮箱稳定性、邮箱反垃圾反病毒性能、邮件收发速度;
2) 通过购买服务,能适应企业不断升级需求;
3) 为员工分配(域名)企业邮箱,便于将流动员工所有业务联系保留和延续下来;
4) 监控邮件(实际为邮件暗抄送功能),以防公司的机密和重要信息流失;
5) 获得高性能邮件海外转发功能,解决国际高效邮件收发、邮件营销有效投递等问题;
6) 出站电子邮件过滤,比如:敏感字过滤、基于政策邮件加密等等;
7) 等等。
四、.Net提供的关于邮件的类库
在.Net2.0之前的版本,使用System.Web.Mail发送邮件,在2.0之后的版本,使用System.Net.Mail来发送邮件.2.0之后的版本主要用到了.Net2.0之后新增的两个类,分别是System.Net.Mail.MailMessage和System.Net.Mail.SmtpClient两个类,在SMTP身份验证方面用到了System.Net.NetworkCredential类。
1、MailMessage类的使用,如下表格:
属性名 | 属性值要求的类型 | 属性值的意义 |
From | MailAddress |
获取或设置此电子邮件的发信人地址。 两者区别:当 Sender与From 都有设定时,Mail Server 会取用Sender 的设定发信,但邮件上的名称会使用 From 的设定,而若不需要 Sender 和 From 同时设定时,則 Sender 可以免设,但 From 一定要设。详细请看:《MailMessage 的 Sender 和From? 傻傻分不清楚》 |
Sender |
||
To | MailAddressCollection | 获取包含此电子邮件的收件人的地址集合。 |
CC | MailAddressCollection | 获取包含此电子邮件的抄送 (CC) 收件人的地址集合。 |
Bcc | MailAddressCollection | 获取包含此电子邮件的密件抄送(BCC) 收件人的地址集合。 |
Attachments | AttachmentCollection | 获取用于存储附加到此电子邮件的数据的附件集合。 |
Headers | NameValueCollection | 获取与此电子邮件一起传输的电子邮件标头。(例如用于:发送DKIM签名的邮件) |
Subject | string | 获取或设置此电子邮件的主题。 |
Body | string | 获取或设置邮件正文。 |
AlternateViews | AlternateViewCollection | 指定一个电子邮件不同格式显示的副本。(eg:发送HTML格式的邮件,可能希望同时提供邮件的纯文本格式,以防止一些收件人使用的电子邮件阅读程序无法显示html内容) |
IsBodyHtml | bool | 默认false。获取或设置指示邮件正文是否为 Html 格式的值。 |
Priority | MailPriority | 默认Normal。获取或设置此电子邮件的优先级。(Normal | Low| High) |
HeadersEncoding | Encoding | 获取或设置此电子邮件的用户定义的自定义标题使用的编码。 |
SubjectEncoding | Encoding | 获取或设置此电子邮件的主题内容使用的编码。 |
BodyEncoding | Encoding | 获取或设置用于邮件正文的编码。 |
ReplyToList | MailAddressCollection |
设置接收方回复邮件时默认的接收地址,eg:你用一个邮箱发信,但却用另一个来收信。 (ReplyTo,表示单个回复地址,已过期,使用ReplyToList代替) |
DeliveryNotificationOptions 注:这个属性要配合BuildDeliveryStatusNotificationString()方法一起使用 |
DeliveryNotificationOptions(枚举) |
// 摘要: |
2、SmtpClient类的使用 如下表格:
属性名 | 属性值要求的类型 | 属性值的意义 |
Host | string | 获取或设置用于 SMTP 事务的主机的名称或 IP 地址。 |
Port | int | 获取或设置用于 SMTP 事务的端口。 |
UseDefaultCredentials | bool |
默认false。 若要使用默认网络凭据,可以将UseDefaultCredentials设置为 true,此时System.Net.CredentialCache.DefaultCredentials(应用程序系统凭证)会随请求一起发送。 如果UseDefaultCredentials属性设置为 false,则连接到服务器时会将 Credentials 属性中设置的值用作凭据。如果UseDefaultCredentials属性设置为 false 并且尚未设置 Credentials 属性,则将邮件以匿名方式发送到服务器。若SMTP 服务器要求在验证客户端的身份则会抛出异常。 |
Credentials | ICredentialsByHost | 获取或设置用于验证发件人身份的凭据。 |
ClientCertificates | X509CertificateCollection | 指定应该使用哪些证书来建立安全套接字层 (SSL) 连接。 |
EnableSsl | bool | 默认false。指定SmtpClient是否使用安全套接字层 (SSL)加密连接。 |
Timeout | int | 默认100000.获取或设置一个值,该值指定同步重载:SmtpClient.Send()调用的超时时间。 |
自建本地SMTP服务器获取邮件时需要使用到的属性 | ||
DeliveryMethod | SmtpDeliveryMethod | 默认NetworkCredential。
// 摘要: |
PickupDirectoryLocation | string | 获取或设置文件夹,应用程序在该文件夹中保存将由本地 SMTP 服务器处理的邮件。 |
TargetName | string | "SMTPSVC/" + this.host。获取或设置在使用扩展保护时用于身份验证的服务提供程序名称 (SPN)。 |
ServicePoint | ServicePoint | 获取用于传输电子邮件的网络连接。(应该会保存TCP连接,避免再次进行TCP的三次握手???) |
五、实战
实战使用QQ邮箱.首先打开“POP3/SMTP服务”,图解如下:
保存授权码,这个很重要!!!
1、简单邮件发送功能
上面两个关键类介绍完之后,就可以开始编写简单的邮件发送功能了.代码如下:
MailMessage mm = new MailMessage(); mm.From = new MailAddress(From, "张三", Encoding.UTF8); mm.To.Add(new MailAddress(To)); mm.BodyEncoding = Encoding.UTF8; mm.SubjectEncoding = Encoding.UTF8; mm.Subject = "this is a test email"; mm.Body = "this is a test body<div><a href="http://www.baidu.com">百度</a></div>"; mm.IsBodyHtml = true; SmtpClient sc = new SmtpClient("smtp.qq.com", 587); sc.Credentials = new NetworkCredential(From,Pwssword);//此处的password参数填刚刚保存的授权码 sc.EnableSsl = true; sc.Send(mm);
ok,如果上面的操作都正确的话,那么邮件将会发送成功。
2、邮件内容内嵌图片和mp3,注:不是以附件的形式发过去
(1)、通过超链接的方式
MailMessage mm = new MailMessage(); mm.From = new MailAddress(From, "张三", Encoding.UTF8); mm.To.Add(new MailAddress(To)); mm.BodyEncoding = Encoding.UTF8; mm.SubjectEncoding = Encoding.UTF8; mm.Subject = "this is a test email"; //通过超链接链接网络上的图片 mm.Body = "this is a test body<div><a href="http://www.baidu.com">百度</a><img src='https://www.baidu.com/img/bd_logo1.png'/></div>"; mm.IsBodyHtml = true; SmtpClient sc = new SmtpClient("smtp.qq.com", 587); sc.Credentials = new NetworkCredential(From,Pwssword);//此处的password参数填刚刚保存的授权码 sc.EnableSsl = true; sc.Send(mm);
(2)、通过AttachmentBase的属性ContentId和ContentDisposition类来实现内嵌资源,代码如下:
对于文件附件,可以使用 ContentDisposition 的属性来设置文件大小、文件的创建日期、上次读取文件的日期以及上次修改文件的日期。对于所有附件,考虑到附件有可能会存储到接收计算机上,可以设置一个建议的文件名。显示电子邮件的软件可以使用 ContentDisposition 中的信息,按发件人预期的方式呈现电子邮件附件。
通过 ContentDisposition 实例的Inline属性实现邮件内嵌资源。如下:
设置附件的ContentId属性为一个自定义名称。
设置附件的ContentDisposition.Inline属性为true。
在邮件的HTML格式正文中以“cid:自定义名称”的方式引用,比如ContentId设为“face”,那么正文中就以“cid:face”作为其URL路径字符串的替代即可。
关于ContentDisposition类的详细信息,请参考MSDN
MailMessage mm = new MailMessage(); mm.From = new MailAddress(From, "张三", Encoding.UTF8); mm.To.Add(new MailAddress(To)); mm.BodyEncoding = Encoding.UTF8; mm.SubjectEncoding = Encoding.UTF8; mm.Subject = "this is a test email"; mm.Attachments.Add(new Attachment(@"C:UsersAdministratorDesktopQQ图片20170813165544.png")); mm.Attachments[0].ContentId = "TestPic"; mm.Attachments[0].ContentDisposition.Inline = true;//设置内嵌图片的关键属性 mm.Attachments[0].NameEncoding = mm.SubjectEncoding = mm.HeadersEncoding = mm.BodyEncoding = Encoding.UTF8; mm.Body = string.Format("this is a test body<div><a href="http://www.baidu.com">百度</a><img src='{0}' /><a href='{0}' target='_blank'>点击新窗口打开图片</a></div>", "cid:" + mm.Attachments[0].ContentId); mm.IsBodyHtml = true; SmtpClient sc = new SmtpClient("smtp.qq.com", 587); sc.Credentials = new NetworkCredential(From,Pwssword);//此处的password参数填刚刚保存的授权码 sc.EnableSsl = true; sc.Send(mm);
(3)、通过AlternateView类和LinkedResource类来实现