.NET Core 使用MailKit发送电子邮件

点击上方蓝字关注“汪宇杰博客”

640?wx_fmt=png

发送邮件通知的功能在各种系统里都很常见。我的博客也能在有新评论、新回复,或者文章被其他网站引用时向管理员发送邮件。那么在.NET Core里,如何实现发送电子邮件呢?

640?wx_fmt=gif

准备工作

我的案例会利用微软outlook.com的个人版邮箱作为发件账号发送邮件,使用SMTP协议。但你也可以使用其他支持SMTP的邮箱系统来做实验。anyway,首先就是,你得有一个邮箱账号啦~

关于 MailKit

很多有经验的.NET老程序员可能会说,发邮件有什么难的,十几年前我们就能用.NET Framework自带的SmtpClient发邮件了,并且.NET Core也能用。为啥还要写这篇文章?

但是,万物皆有始有终,最近我突然发现,SmtpClient 已经被微软标记为弃用:

640?wx_fmt=png640?wx_fmt=png

并且微软官方钦点了一个继任者:MailKit,也就是本文要介绍的东西。

https://github.com/jstedfast/MailKit

这是一个基于MimeKit的跨平台.NET邮件库,支持IMAP、POP3、SMTP协议。它相比.NET自带的SmtpClient,支持更广泛的协议和更现代的电子邮件标准。因此微软官方建议,SmtpClient只用来兼容老应用,如果开发新应用的话,直接使用MailKit。

并且,它是在MIT协议下开源的。意味着非常自由的使用,也可以由全世界的.NET开发者参与贡献,一起维护和完善这个东西。

640?wx_fmt=gif

使用SMTP协议发送邮件

我得到这个好东西以后,第一步就是将使用SmtpClient的老代码迁移到MailKit。因此,我的案例里只使用SMTP这一种协议来发邮件。

安装包

首先,使用NuGet安装MailKit:

Visual Studio

Install-Package MailKit

.NET Core CLI

dotnet add package MailKit

构建 MimeMessage

MimeMessage是MailKit里代表一封电子邮件的对象,它和.NET自带的MailMessage类型非常类似。比如添加主题和发件人:

var messageToSend = new MimeMessage

{

    Sender = new MailboxAddress("发件人姓名", "发件人Email地址"),

    Subject = "主题",

};

添加发件人信息和以前有所不同,MailKit居然支持多个发件人,所以From是一个集合类型,要通过Add方法来添加:

messageToSend.From.Add(new MailboxAddress("发件人姓名", "发件人邮箱账号名"));

邮件正文(Body属性)支持多种格式,最常用的是纯文本和HTML。需要用TextPart类来安排,TextPart的构造函数里可以指定正文格式,例如HTML:

messageToSend.Body = new TextPart(TextFormat.Html) { Text = bodyText };

或者纯文本

messageToSend.Body = new TextPart(TextFormat.Plain) { Text = bodyText };

添加收件人信息:

messageToSend.To.Add(new MailboxAddress("收件人Email地址"));

添加抄送(CC)信息:

messageToSend.Cc.Add(new MailboxAddress("抄送者Email地址"));

使用Outlook.com发送电子邮件

微软Office 365的outlook支持SMTP协议。

服务器地址:smtp-mail.outlook.com

端口:587

SSL:支持

以下代码演示了几个步骤:

  1. 注册邮件发送成功后的事件

  2. 连接服务器

  3. 验证账号

  4. 发送邮件

  5. 断开连接

using (var smtp = new MailKit.Net.Smtp.SmtpClient())

{

    smtp.MessageSent += (sender, args) => { // args.Response };

    smtp.ServerCertificateValidationCallback = (s, c, h, e) => true;

    await smtp.ConnectAsync("smtp-mail.outlook.com", 587, SecureSocketOptions.StartTls);

    await smtp.AuthenticateAsync("账号", "密码");

    await smtp.SendAsync(messageToSend);

    await smtp.DisconnectAsync(true);

}

MessageSent事件里可以通过args参数,获得服务器的响应信息,以便于记录Log。

连接outlook.com的服务器需要设置为SecureSocketOptions.StartTls,不然会拒绝连接。对于其他服务器,可以试试 SecureSocketOptions.Auto

效果

以下是MailKit在我的博客系统使用的邮件库(Edi.TemplateEmail)中发送邮件的效果:

640?wx_fmt=png640?wx_fmt=png640?wx_fmt=gif

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/316297.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

P3327 [SDOI2015]约数个数和

P3327 [SDOI2015]约数个数和 题意: 设 d(x) 为 x 的约数个数,给定 n,m,求 ∑i1n∑j1md(i,j)\sum_{i1}^{n}\sum_{j1}^{m}d(i,j)∑i1n​∑j1m​d(i,j) 题解: 代码: // Problem: P3327 [SDOI2015]约数个数和 // Conte…

[CQOI2018] 解锁屏幕(状压dp)

problem luogu-P4460 solution 题面以及数据告诉我们显然是状压 dpdpdp。 设 f(s,i):f(s,i):f(s,i): 经过的点集 sss 最后一次画的点为 iii 的方案数。 直接枚举下一个之前没被画的点 jjj 转移即可。 f(s∣2j,j)←f(s,i)f(s|2^j,j)\leftarrow f(s,i)f(s∣2j,j)←f(s,i)。 …

C#并行编程(6):线程同步面面观

理解线程同步线程的数据访问在并行(多线程)环境中,不可避免地会存在多个线程同时访问某个数据的情况。多个线程对共享数据的访问有下面3种情形:多个线程同时读取数据;单个线程更新数据,此时其他线程读取数据…

P2522 [HAOI2011]Problem b

P2522 [HAOI2011]Problem b 题意: 对于给出的 n 个询问,每次求有多少个数对 (x,y),满足 a≤x≤b,c≤y≤d,且 gcd(x,y)k,gcd(x,y) 函数为 x 和 y 的最大公约数。 题解: 这个题跟P3455 [POI20…

[十二省联考 2019] 异或粽子(可持久化字典树 + 二叉堆)

problem luogu-P5283 小粽是一个喜欢吃粽子的好孩子。今天她在家里自己做起了粽子。 小粽面前有 nnn 种互不相同的粽子馅儿,小粽将它们摆放为了一排,并从左至右编号为 111 到 nnn。 第 iii 种馅儿具有一个非负整数的属性值 aia_iai​。 每种馅儿的数…

.NET Core/Framework 创建委托以大幅度提高反射调用的性能

都知道反射伤性能,但不得不反射的时候又怎么办呢?当真的被问题逼迫的时候还是能找到解决办法的。为反射得到的方法创建一个委托,此后调用此委托将能够提高近乎直接调用方法本身的性能。(当然 Emit 也能够帮助我们显著提升性能&…

[省选联考 2020 A/B 卷] 冰火战士(树状数组上二分)

文章目录problemsolution(10pts)code(10pts)solution(30pts)code(30pts)solution(60pts)code(60pts)solution(100pts)code(100pts)problem luogu-P6619 一场比赛即将开始。 每位战士有两个属性:温度和能量。 有两派战士: 冰系战士的技能会对周围造成…

P1829 [国家集训队]Crash的数字表格 / JZPTAB

P1829 [国家集训队]Crash的数字表格 / JZPTAB 题意&#xff1a; 求∑i1n∑j1mlcm(i,j)\sum_{i1}^{n}\sum_{j1}^{m}lcm(i,j)∑i1n​∑j1m​lcm(i,j) 1<n<m<1e7 结果mod20101009 题解&#xff1a; 跟这个题P3911 最小公倍数之和很相近&#xff0c;但是本题数据范围大…

C# 跨设备前后端开发探索

每个人都拥有 好奇心&#xff0c;好奇心驱使着我们总是去尝试做一些有趣的事情。带起你的好奇心&#xff0c;本文将使用 C# 开发各种各样好玩的东西。每个人都拥有 好奇心&#xff0c;好奇心驱使着我们总是去尝试做一些有趣的事情。比如这件事&#xff1a;在好奇心的驱使下&…

Docker最全教程之Python爬网实战(二十二)

Python目前是流行度增长最快的主流编程语言&#xff0c;也是第二大最受开发者喜爱的语言&#xff08;参考Stack Overflow 2019开发者调查报告发布&#xff09;。笔者建议.NET、Java开发人员可以将Python发展为第二语言&#xff0c;一方面Python在某些领域确实非常犀利&#xff…

P2870 [USACO07DEC]Best Cow Line G

P2870 [USACO07DEC]Best Cow Line G 题意&#xff1a; 给你一个字符串&#xff0c;每次从首或尾取一个字符组成字符串&#xff0c;问所有能够组成的字符串中字典序最小的一个。 题解&#xff1a; 现在要组成字典序最小的&#xff0c;那我们每次就尽可能取小的 我们从两端开…

[APIO2014] 序列分割(斜率优化dp)

problem luogu-P3648 你正在玩一个关于长度为 nnn 的非负整数序列的游戏。这个游戏中你需要把序列分成 k1k1k1 个非空的块。 为了得到 k1k1k1 块&#xff0c;你需要重复下面的操作 kkk 次&#xff1a; 选择一个有超过一个元素的块&#xff08;初始时你只有一块&#xff0c;…

中间件是什么?在.NET Core中的工作原理又是怎样的呢?

本文出自《从零开始学ASP.NET CORE MVC》推荐文章&#xff1a;ASP.NET Core appsettings.json文件ASP.NET Core 中的中间件(Middleware)在这个视频中&#xff0c;我们将了解&#xff0c;ASP.NET Core 中的中间件是 什么&#xff1f;中间件很重要&#xff0c;尤其是在你想当架构…

P2408 不同子串个数

P2408 不同子串个数 题意&#xff1a; 给你一个长为 n 的字符串&#xff0c;求不同的子串的个数。 我们定义两个子串不同&#xff0c;当且仅当有这两个子串长度不一样或者长度一样且有任意一位不一样。 子串的定义&#xff1a;原字符串中连续的一段字符组成的字符串。 题解…

[SDOI2016] 生成魔咒(后缀数组SA + st表 + set)动态不同子串个数

problem luogu-P4070 魔咒串由许多魔咒字符组成&#xff0c;魔咒字符可以用数字表示。例如可以将魔咒字符 1,21,21,2 拼凑起来形成一个魔咒串 [1,2][1,2][1,2]。 一个魔咒串 S 的非空字串被称为魔咒串 S 的生成魔咒。 例如 S[1,2,1]S[1,2,1]S[1,2,1] 时&#xff0c;它的生成…

P4248 [AHOI2013]差异

P4248 [AHOI2013]差异 题意&#xff1a; ∑1≤i<j≤nlen(Ti)len(Tj)−2∗lcp(Ti,Tj)\sum_{1\leq i<j\leq n}len(T_{i})len(T_{j})-2*lcp(T_{i},T_{j})∑1≤i<j≤n​len(Ti​)len(Tj​)−2∗lcp(Ti​,Tj​) 题解&#xff1a; ∑1≤i<j≤nlen(Ti)len(Tj)\sum_{1\le…

从高德采集最新的省市区三级坐标和行政区域边界,用js在浏览器中运行

本文描述的是对国家统计局于2019-01-31发布的《2018年统计用区划代码和城乡划分代码(截止2018年10月31日)》中省市区三级的坐标和行政区域边界的采集。本文更新&#xff08;移步查阅&#xff09;&#xff1a;19-04-15 新采集了2018的省市区三级的坐标和行政区域边界数据csv格式…

[JSOI2016] 最佳团体(0/1分数规划 + 树形dp)

problem luogu-P4322 solution 假设每个人是否被招募&#xff0c;用 xi{0,1}x_i\{0,1\}xi​{0,1} 代替&#xff0c;max⁡∑pi∗xi∑si∗xi\max\frac{\sum p_i*x_i}{\sum s_i*x_i}max∑si​∗xi​∑pi​∗xi​​。 0/10/10/1 分数规划标准式子。 二分答案 ans∑pi∗xi∑si∗…

Display Substring

Display Substring 题意&#xff1a; 一个长度为n的字符串&#xff0c;每个字符有自己的价值&#xff0c;求第k小价值的不重复子串价值 题解&#xff1a; 首先众所周知&#xff0c;所有子串都可以用后缀的前缀来表示&#xff0c;这就和后缀数组扯上关系了 我们可以直接二分…

使用 DotNet CLI 创建自定义的 WPF 项目模板

描述当我们安装完 DotNetCore 3.0 版本的 SDK 后&#xff0c;我们就可以创建基于 DotNetCore 的 WPF 项目模板&#xff0c;通过如下 CLI 可以方便快捷的创建并运行我们的项目&#xff1a;Copydotnet new wpf -n WpfAppcd WpfAppdotnet restoredotnet run做过 WPF 开发的朋友都知…