System.Net邮件发送功能踩过的坑
System.Net邮件发送功能踩过的坑
1.EazyEmail邮件发送类库
Net 类库自带了邮件发送功能。笔者对该类库,从使用的角度进行了二次封装,nuget上可搜索EazyEmail,注入容器时通过委托来获得邮箱服务器的配置地址以及发送地址直接调用send方法即可。
容器注入代码
services.AddEmailKit(() =>
{
EmailConfig emailConfig = new EmailConfig( );
#region 163网易邮件发送
emailConfig.EmailSmtpAddress = "smtp.163.com";
emailConfig.EmalHostPort = 587;
emailConfig.SendEmailAccount = "13737732703@163.com";
emailConfig.SendEmailPassWord = "******";
#endregion
#region qq 邮件发送
// emailConfig.EmailSmtpAddress = "smtp.qq.com";
// emailConfig.EmalHostPort = 587;
// emailConfig.SendEmailAccount = "87888397@qq.com";
// emailConfig.SendEmailPassWord = "*****";
#endregion
return emailConfig;
});
发送代码
MailBox QqMailbox = new MailBox();
QqMailbox.To = "87888397@qq.com";
QqMailbox.Body = "qqfadsfa邮箱测试";
QqMailbox.Cc = "935467953@qq.com";
QqMailbox.Subject = "qq邮fadfa箱测试";
emailQueueService.Enqueue(QqMailbox);
EazyEmail 内置阻塞队列,只要队列有邮件,里面开了一个线程会不断地发送,发送完毕会阻塞住,对应线程执行权也会回归线程池,一旦继续有邮件,线程自动唤醒会继续发送邮件。有关EazyEmail的使用与设计思路有需要介绍可留言,可另起一篇作讲解,已经上传到nuget,可自行搜索EazyEmail去使用,使用非常方便。

EazyEmail类库源码 github地址需要者可自行下载
2.邮件发送授权码与邮件密码
第三方客户端登录邮件服务器来进行发送邮件,接收邮件已经极为普遍,某种场景下是代码里嵌入发送邮件信息,当然也包含了发送邮件的密码,近两年邮件服务商为了提高邮件的保密性,网易与qq邮箱规定了第三方客户端发送邮件只能通过发送授权码。
网易发送授权码生成过程:

开启所需要的邮件发送服务跟接收服务

手机微信扫描发送二维码

手机短信发送之后,点击我已发送 生成授权码

此授权码可直接用来作为应用程序的发送密码。
qq邮箱发送授权码生成过程:
生成授权码步骤,设置,账户往下拉。

点击生成授权码,短信发送,我已发送,即可生成对应授权码。

备注:qq邮箱多年之前已经采用授权码方式,而网易,笔者在15年时测试第三方客户端是可以用密码发送的,当然现在15年设置开启了pop/smtp,或者imap/smtp服务,当时没有生成授权码的依然能用密码发送,只不过当你生成过授权码之后就在网易服务商这里就再也不能用密码发送了,第三方只能通过授权码发送。即便你删除完授权码,那么pop/smtp,或者imap/smtp服务就会自动关闭。
3.通过邮件密码来发送邮件
你是否同时会有这样的疑问,能否通过邮箱的密码来发送邮件呢?笔者之所以有如下思考,是基于用户的使用方便程度来考虑:
- 用户没有授权码的概念;
- 使用简便的角度来看,直接账户,登录密码是最方便的;
一开始,笔者心里也没有答案,但是想到,公司的邮箱密码是可以记录到foxmail,然后通过这个客户端来进行邮件的发送与接收管理邮箱。但是我直接用代码来发送邮件却不成功,报失败。失败代码如下:
static void Main(string[] args)
{
try
{
var client = new SmtpClient
{
DeliveryMethod = SmtpDeliveryMethod.Network,
EnableSsl = true,
Host = "smtp.lead-it.cn",
Port = 465
};
client.Credentials = new NetworkCredential("hekun@lead-it.cn", "*********");
MailMessage msg = new MailMessage("hekun@lead-it.cn", "87888397@qq.com", "测试", "邮箱测试");
client.Send(msg);
Console.WriteLine("邮件已发送,请注意查收!");
Console.ReadKey();
}
catch (SmtpException ex)
{
Console.WriteLine("发送邮件失败:" + ex.Message);//输出错误信息
}
}

4.Wireshark抓包分析
遇到困难自然是迎难而上,foxmail能做到的事,我们一样能做到。只需要foxmail的发送邮件的过程抓包,一一分析,然后自己邮件发送过程,对比,找出差异就能定位问题。
抓了小半天包,没有结果,抓不到pop跟SMTP协议的包。
后面静下心来仔细分析是因为公司邮箱服务器(163企业邮箱服务器,管理员设置了ssl)加了ssl认证。
下面只能贴上163服务器不加密的发送过程与接收过程的wireshark抓包,忘记密码的同学可以自己抓包找回密码,仅限在不加密的情况下。
通过pop协议接收邮件。想了解IMAP协议的自行抓包,方法一样

smtp发送抓包如下,可以看到发送时用户名密码是加密的

5.通过密码SSL发送成功
先看下发送成功代码
static void Main(string[] args)
{
try
{
ServicePointManager.ServerCertificateValidationCallback = (s, cert, chain, errors) => true;
var client = new SmtpClient
{
DeliveryMethod = SmtpDeliveryMethod.Network,
EnableSsl = true,
Host = "smtp.lead-it.cn",
Port = 587
};
client.Credentials = new NetworkCredential("hekun@lead-it.cn", "********");
MailMessage msg = new MailMessage("hekun@lead-it.cn", "87888397@qq.com", "测试", "邮箱测试");
client.Send(msg);
Console.WriteLine("邮件已发送,请注意查收!");
Console.ReadKey();
}
catch (SmtpException ex)
{
Console.WriteLine("发送邮件失败:" + ex.Message);//输出错误信息
}
}
5.1 微软不支持在465的ssl
通过不断的搜索,与调试发现。
oschina上有这样一篇文章
Microsoft is not supporting SSL over port 465 in c# 4/.NET 4.
Microsoft only supports SSL on 587 through "STARTTLS".
大意是微软不支持SSL端口开在465,有可能465端口被微软的其他库占用。而一般邮件服务商会开多个ssl端口,比如587。当然如果是公司自己搭建的邮件服务器就需要注意这个坑了,你只开了465 ssl端口就意味着永远用不了微软爸爸的邮件库。
5.2 ssl证书
解决了上面的5.1,又有了5.2问题如下:

大概含义是ssl证书无效。
在stackoverflow上找到了答案:
the-remote-certificate-is-invalid
如果没有ssl证书,直接加入下面语句,返回true,有些信息就没加密。需要加密的读者自行搜索加入ssl文件证书。
ServicePointManager.ServerCertificateValidationCallback = (s, cert, chain, errors) => true;
公司企业邮箱(企业级的网易邮箱允许第三方客户端不通过授权码)通过邮件密码发送邮件到qq邮箱,qq邮箱收到邮件如下:

至此,问题解决。
System.Net邮件发送功能踩过的坑的更多相关文章
- SpringBoot 2.X从0到1实现邮件发送功能
Spring中提供了JavaMailSender接口实现邮件发送功能,在SpringBoot2.X中也封装了发送邮件相关的Starter并且提供了自动化配置. 本文目录 一.添加对应的Starter二 ...
- .NET开发邮件发送功能的全面教程(含邮件组件源码)
今天,给大家分享的是如何在.NET平台中开发“邮件发送”功能.在网上搜的到的各种资料一般都介绍的比较简单,那今天我想比较细的整理介绍下: 1) 邮件基础理论知识 2) ...
- .NET开发邮件发送功能
.NET开发邮件发送功能 今天,给大家分享的是如何在.NET平台中开发“邮件发送”功能.在网上搜的到的各种资料一般都介绍的比较简单,那今天我想比较细的整理介绍下: 1) 邮件基础理论知 ...
- 用ASP.NET Core 1.0中实现邮件发送功能-阿里云邮件推送篇
在上篇中用MailKit实现了Asp.net core 邮件发送功能,但一直未解决阿里云邮件推送问题,提交工单一开始的回复不尽如人意,比如您的网络问题,您的用户名密码不正确等,但继续沟通下阿里云客户还 ...
- redmine邮件发送功能配置详解
redmine的邮件发送功能还是很有用的.像项目有更新啦,任务分配啦,都能邮件发送的相关责任人.我自己在linux服务器上安装并启动了redmine后,邮件一直发送了不了.查了网上的资料,都是讲修改下 ...
- shell邮件发送功能实现
本文中以163邮箱为例,测试shell邮件发送功能.常见的工具有:mailx.sendmail.mutt等. 1.设置邮件客户端 (1)启用pop3.smtp服务,以支持第三方客户端支持 (2)设置授 ...
- spring-boot-route(二十二)实现邮件发送功能
在项目开发中,除了需要短信验证外,有时候为了节省 短信费也会使用邮件发送.在Spring项目中发送邮件需要封装复杂的消息体,不太方便.而在Spring Boot项目中发送邮件就太简单了,下面一起来看看 ...
- 结合ABP源码实现邮件发送功能
1. 前言 2. 实现过程 1. 代码图(重) 2.具体实现 2.1 定义AppSettingNames及AppSettingProvider 2.2 EmailSenderConfiguration ...
- SSH项目里面 忘记密码的邮件发送功能
package com.xxx.util; import java.util.Date; import java.util.Properties; import javax.mail.Address; ...
随机推荐
- JavaFX ComboBox的选中事项
参考1:https://blog.csdn.net/mexel310/article/details/37909205 参考2:https://blog.csdn.net/maosijunzi/art ...
- vue项目的elementui的form表单label的对齐方式和 el-date-picker 的长度设置
1.先按照官网的 :label-position 属性玩了一下毫无效果:发现单独使用这个属性是无效的,必须和 label-width 属性一起使用才生效: 如: <el-form :mod ...
- 远程触发Jenkins的Pipeline任务
场景 虽然能配置提交代码时触发Jenkins任务,但有时并不需要每次提交代码都触发,而是仅在有需要时才执行. 除了在Jenkins页面上手动执行任务,还可以向Jenkins网站发起HTTP请求,触发指 ...
- 如何让程序像人一样的去批量下载歌曲?Python爬取付费歌曲
前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 今天来教大家一个自动化爬虫的工具 selenium selenium Se ...
- Cesium.Viewer
<!DOCTYPE html><html lang="en"><head> <meta charset="utf-8" ...
- 技术心得丨一种有效攻击BERT等模型的方法
Is BERT Really Robust? A Strong Baseline for Natural Language Attack on Text Classification and Enta ...
- 【C语言/C++编程学习笔记】:通俗易懂讲解 - 链表!学不会?不存在的!
C语言是面向过程的,而C++是面向对象的 C和C++的区别: C是一个结构化语言,它的重点在于算法和数据结构.C程序的设计首要考虑的是如何通过一个过程,对输入(或环境条件)进行运算处理得到输出(或实现 ...
- xuexi
1.内存的编址方法就是内存地址与内存单元格一一对应且永久绑定.计算机的cpu只认识内存地址,不关心内存单元格的位置和内容.通过硬件的设计来达到通过内存地址找到内存单元格. 2.内存的编址是以字节为单位 ...
- Eclipse JSP +Tomcat 环境搭建 错误记录
环境搭建请参考原文:https://www.cnblogs.com/james-lee/p/5964238.html 错误1:运行时,弹出如下错误:(如果没有此错误,请忽略) 原因是,我们之前点击了T ...
- Linux用户和组管理命令-用户属性修改usermod
用户属性修改 usermod 命令可以修改用户属性 格式: usermod [OPTION] login 常见选项: -u UID: 新UID -g GID: 新主组 -G GROUP1[,GROUP ...