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.通过邮件密码来发送邮件

你是否同时会有这样的疑问,能否通过邮箱的密码来发送邮件呢?笔者之所以有如下思考,是基于用户的使用方便程度来考虑:

  1. 用户没有授权码的概念;
  2. 使用简便的角度来看,直接账户,登录密码是最方便的;

一开始,笔者心里也没有答案,但是想到,公司的邮箱密码是可以记录到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邮件发送功能踩过的坑的更多相关文章

  1. SpringBoot 2.X从0到1实现邮件发送功能

    Spring中提供了JavaMailSender接口实现邮件发送功能,在SpringBoot2.X中也封装了发送邮件相关的Starter并且提供了自动化配置. 本文目录 一.添加对应的Starter二 ...

  2. .NET开发邮件发送功能的全面教程(含邮件组件源码)

    今天,给大家分享的是如何在.NET平台中开发“邮件发送”功能.在网上搜的到的各种资料一般都介绍的比较简单,那今天我想比较细的整理介绍下: 1)         邮件基础理论知识 2)         ...

  3. .NET开发邮件发送功能

    .NET开发邮件发送功能 今天,给大家分享的是如何在.NET平台中开发“邮件发送”功能.在网上搜的到的各种资料一般都介绍的比较简单,那今天我想比较细的整理介绍下: 1)         邮件基础理论知 ...

  4. 用ASP.NET Core 1.0中实现邮件发送功能-阿里云邮件推送篇

    在上篇中用MailKit实现了Asp.net core 邮件发送功能,但一直未解决阿里云邮件推送问题,提交工单一开始的回复不尽如人意,比如您的网络问题,您的用户名密码不正确等,但继续沟通下阿里云客户还 ...

  5. redmine邮件发送功能配置详解

    redmine的邮件发送功能还是很有用的.像项目有更新啦,任务分配啦,都能邮件发送的相关责任人.我自己在linux服务器上安装并启动了redmine后,邮件一直发送了不了.查了网上的资料,都是讲修改下 ...

  6. shell邮件发送功能实现

    本文中以163邮箱为例,测试shell邮件发送功能.常见的工具有:mailx.sendmail.mutt等. 1.设置邮件客户端 (1)启用pop3.smtp服务,以支持第三方客户端支持 (2)设置授 ...

  7. spring-boot-route(二十二)实现邮件发送功能

    在项目开发中,除了需要短信验证外,有时候为了节省 短信费也会使用邮件发送.在Spring项目中发送邮件需要封装复杂的消息体,不太方便.而在Spring Boot项目中发送邮件就太简单了,下面一起来看看 ...

  8. 结合ABP源码实现邮件发送功能

    1. 前言 2. 实现过程 1. 代码图(重) 2.具体实现 2.1 定义AppSettingNames及AppSettingProvider 2.2 EmailSenderConfiguration ...

  9. SSH项目里面 忘记密码的邮件发送功能

    package com.xxx.util; import java.util.Date; import java.util.Properties; import javax.mail.Address; ...

随机推荐

  1. linux下各种骚操作

    (备注:不定时更新) 1. ctrl+l  清屏快捷键,相当于clear 2. !+命令开头部分   执行最近执行的此条命令   ### 如!vi  编辑上一次用vi打开的文件, 3. echo $$ ...

  2. shell-字符串多操作符综合实践多案例

    1. 字符串测试举例     提示:下面的$file并未定义,而$file1 在上面测试中已定义. 范例1:单条件字符串测试: [root@test-1 ~]# file1=/etc/services ...

  3. shell-脚本开发基本规范及习惯

    1.shell-脚本开发基本规范及习惯 1.开头指定脚本解析器 #!/bin/sh 或#!/bin/bash 2.开头加版本版权等信息 #Date: 2018/3/26 #Author: zhangs ...

  4. protoc-c 阅读笔记

    以前和山哥做过类似的,最近想起来,抽空又看了下 protoc-c. 山哥做的报文流向: rpc -> lydtree -> motree -> struct 涉及的细节很多 1) l ...

  5. 2016年 实验二、C2C模拟实验

    实验二.C2C模拟实验 [实验目的] 掌握网上购物的基本流程和C2C平台的运营 [实验条件] ⑴.个人计算机一台 ⑵.计算机通过局域网形式接入互联网. (3).奥派电子商务应用软件 [知识准备] 本实 ...

  6. 基于python实现顺序存储的队列代码

    """ 队列-顺序存储 seqqueue.py 代码实现 """ # 自定义异常类 class QueueError(Exception): ...

  7. 网络爬虫养成记(第一天)——安装Scrapy

    古人云:工欲善其事,必先利其器.在网络爬虫中,Scrapy无疑是一把利器,那么,今天我们来谈谈Scrapy的安装. 幸运的是,Scrapy已经支持Python3.4+了,也就是说,我们可以在pytho ...

  8. hdu6115 Factory (LCA + 倍增)

    Factory Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Others)Total ...

  9. Vue留言 checked框案列

    在命令行窗口输入vue create "工程名"命令 来创建vue脚手架

  10. 浅谈1——用Eclipse调试JAVA程序

    本篇博客主要介绍如何用Eclipse调试简单的JAVA程序. 1.如下图,一个简单的JAVA程序  2.设置断点. 方法:选中需设置断点的行代码,按快捷键Ctrl+Shift+B,设置断点: 断点设置 ...