一封最复杂的电子邮件的基本情况为:含有邮件正文和邮件附件,邮件正文可以同时使用HTML格式和普通文本格式表示,并且HTML格式的正文中又引用了其他的内嵌资源。对于这种最复杂的电子邮件,可以采用如图所示的MIME消息结构进行描述。

一封MIME邮件中的MIME消息可以有三种组合关系:混合、关联、选择,它们对应MIME类型如下:

1、multipart/mixed

表示消息体中的内容是混和组合类型,内容可以是文本、声音和附件等不同邮件内容的混和体,例如上图中的整封邮件的MIME类型就必须定义为multipart/mixed。

2、multipart/related

表示消息体中的内容是关联(依赖)组合类型,例如图5中的邮件正文要使用HTML代码引用内嵌的图片资源,它们组合成的MIME消息的MIME类型就应该定义为multipart/related,表示其中某些资源(HTML代码)要引用(依赖)另外的资源(图像数据),引用资源与被引用的资源必须组合成multipart/related类型的MIME组合消息。

3、multipart/alternative

表示消息体中的内容是选择组合类型,例如一封邮件的邮件正文同时采用HTML格式和普通文本格式进行表达时,就可以将它们嵌套在一个multipart/alternative类型的MIME组合消息中。这种做法的好处在于如果邮件阅读程序不支持HTML格式时,可以采用其中的文本格式进行替代。邮件内容可以只带有一种格式,是可选类型(即邮件正文可以只是普通文本,也可以只是html格式)。

下面就演示一下mailkit发送一封文本、html、内嵌图片,附件的邮件。mailkit提供了两种方式供我们选择:

注意点:Imap协议本身不支持中文,需转成base64编码或"quoted-printable"编码编码。这里要再提出一个问题,如果我们要写一个中文的标题应该怎么写?你会说,改 subject 那里为"中文标题"就可以啦。如果我们这样做的话,确实对方可以收到一封中文的邮件。但我要说的是这样做是错误的。这是因为mailkit帮我们转了编码方式。

方式一:

 var message = new MimeMessage();
message.To.Add(new MailboxAddress("xxxx@126.com", "xxxx@126.com"));//收件人邮箱
message.From.Add(new MailboxAddress("xxxx@163", "xxxx@163.com"));//发件人邮件
message.Subject = "邮件测试主题2"; var builder = new BodyBuilder();
var image = builder.LinkedResources.Add(path);
//组合消息中的内嵌资源指定一个唯一标识号
image.ContentId = MimeUtils.GenerateMessageId(); var plain = new TextPart("plain")
{
Text = @"Hey AnLong[cid:" + image.ContentId + "]"
};
var html = new TextPart("html")
{
Text = @"<p>Hey AnLong<br>
<p>Will you be my +1<br>
<center><img src=""cid:" + image.ContentId + @"""></center>"
}; // create an image attachment for the file located at path
var attachment = new MimePart("image", "png")
{
ContentObject = new ContentObject(File.OpenRead(path), ContentEncoding.Default),
//指定邮件阅读程序处理数据内容的方式,有inline和attachment两种标准方式,inline表示直接处理,而attachment表示当做附件处理。
ContentDisposition = new ContentDisposition(ContentDisposition.Attachment),
//指定MIME消息体中的内容所采用的邮件编码方式
ContentTransferEncoding = ContentEncoding.Base64,
//表示MIME消息体的内容为邮件附件,附件名
FileName = Path.GetFileName(path)
}; //表示消息体中的内容是选择组合类型
var alternative = new Multipart("alternative");
alternative.Add(plain);
alternative.Add(html); //表示消息体中的内容是关联(依赖)组合类型
var relatavenative = new Multipart("related");
relatavenative.Add(alternative);
relatavenative.Add(image); // now create the multipart/mixed container to hold the message text and the
// image attachment
var multipart = new Multipart("mixed");
multipart.Add(relatavenative);
multipart.Add(attachment);
message.Body = multipart; using (var client = new MailKit.Net.Smtp.SmtpClient())
{
client.Connect("smtp.163.com", , true); // Note: since we don't have an OAuth2 token, disable
// the XOAUTH2 authentication mechanism.
client.AuthenticationMechanisms.Remove("XOAUTH2"); // Note: only needed if the SMTP server requires authentication
client.Authenticate("xxxx@163.com", ""); client.Send(message);
client.Disconnect(true);
}

方式二:

 var message = new MimeMessage();
message.To.Add(new MailboxAddress("xxxx@126.com", "xxxx@126.com"));//收件人
message.From.Add(new MailboxAddress("xxxx", "xxxx@163.com"));//发件人
message.Subject = "邮件测试主题2"; var builder = new BodyBuilder();
var image = builder.LinkedResources.Add(path);
image.ContentId = MimeUtils.GenerateMessageId(); builder.TextBody = string.Format(@"[cid:{0}] Hey AnLong", image.ContentId);
builder.HtmlBody = string.Format(@"<p>Hey anlong</p><p>Will you be my +1</p><center><img src=""cid:{0}""></center>", image.ContentId); // We may also want to attach a calendar event for Monica's party...
builder.Attachments.Add(@"C:\Users\Joey\Documents\party.ics"); message.Body = builder.ToMessageBody(); using (var client = new MailKit.Net.Smtp.SmtpClient())
{
client.Connect("smtp.163.com", , true); // Note: since we don't have an OAuth2 token, disable
// the XOAUTH2 authentication mechanism.
client.AuthenticationMechanisms.Remove("XOAUTH2"); // Note: only needed if the SMTP server requires authentication
client.Authenticate("xxxx@163.com", ""); client.Send(message);
client.Disconnect(true);
}

通过上述方式组合成一封完整的邮件,然后发送即可。

MailKit---发送邮件的更多相关文章

  1. 使用 MimeKit 和 MailKit 发送邮件

    MimeKit 给.NET 社区带来了一流的 MIME 解析器,它能处理复杂的各种Mime, 性能好.而且开箱即用支持 S/MIME 和 PGP.MimeKit 和 MailKit 支持最新的国际化的 ...

  2. 使用Volo.Abp.MailKit发送邮件

    Volo.Abp.MailKit封装继承MailKit库,为Abp邮件发送提供了快捷实现. 邮箱配置 qq邮箱支持smtp功能,需要去申请开通.参考qq邮箱设置,最重要的是smtp发送邮件,qq邮箱对 ...

  3. JFinal项目发送邮件——jfinal-mail-plugin

    JFianl框架: JFinal 是基于 Java 语言的极速 WEB + ORM 框架,其核心设计目标是开发迅速.代码量少.学习简单.功能强大.轻量级.易扩展.Restful.在拥有Java语言所有 ...

  4. 使用MailKit收发邮件

    .Net BCL库中对于邮件的支持只有SmtpClient一个,它只能进行简单的邮件的发送操作,并且不支持POP3和SMTP,无法接收邮件,用起来有诸多不便. 今天看到园子里有文章(使用 MimeKi ...

  5. Asp.Net Core 快速邮件队列设计与实现

    发送邮件几乎是软件系统中必不可少的功能,在Asp.Net Core 中我们可以使用MailKit发送邮件,MailKit发送邮件比较简单,网上有许多可以参考的文章,但是应该注意附件名长度,和附件名不能 ...

  6. MailKit/MimeKit 发送邮件

    MimeKit / MailKit 支持最新的国际化的电子邮件标准,是.NET 中为一个支持完整支持这些标准电子邮件库,最近正式发布了1.0版本.如果你想做所有与的电子邮件相关的事情,看看 MimeK ...

  7. 解决.NET Core中MailKit无法使用阿里云邮件推送服务的问题

    在博问中(.net core怎么实现邮件发送)知道了MailKit无法使用阿里云邮件推送服务发送邮件的问题,自已实测也遇到同样的问题,而用自己搭建的邮件服务器没这个问题. 于是,向阿里云提交了工单.. ...

  8. 在ASP.NET Core 1.0中如何发送邮件

    (此文章同时发表在本人微信公众号"dotNET每日精华文章",欢迎右边二维码来关注.) 题记:目前.NET Core 1.0中并没有提供SMTP相关的类库,那么要如何从ASP.NE ...

  9. .NET 通过SmtpClient发送邮件 提示 4.7.1 service unavailable try again later 解决办法

    最近用C#的SmtpClient发送电子邮件碰到这个错误: 正在处理错误. 服务器响应为:4.7.1 Service unavailable - try again later 换了其他的SMTP服务 ...

  10. 跨平台的.NET邮件协议MailKit组件解析

    发起的.NET Core开源组织号召,进展的速度是我自己也没有想到的,很多园友都积极参与(虽然有些人诚心砸场子,要是以我以前的宝脾气,这会应该被我打住院了吧,不过幸好是少数,做一件事总有人说好,也有人 ...

随机推荐

  1. 【Python】- pytharm 中import时无法识别自己写的程序

    右键点击自己的工作空间,找下面的Mark Directory as(将目录标记为) 选择Source Root,就可以解决上面的问题了,如图

  2. swagger-ui enum select

    swagger-ui enum select Array[string] https://dejanstojanovic.net/aspnet/2018/march/displaying-multip ...

  3. Codeforces Round #428 (Div. 2) B

    B. Game of the Rows(贪心) 题意: 有k种颜色,每种有\(a_i\)个,将这k种颜色放在一个\(n * 8格子里\) 放置规则不能出现两个不同颜色在相邻的格子里,相邻的定义为在同一 ...

  4. sql或oracle插入数据时进行md5加密

    1.sql简单直接调用: SELECT hashbytes(') ; 2.oracle要复杂些 首写需要建函数: CREATE OR REPLACE FUNCTION MD5( passwd IN V ...

  5. 《R语言实战》读书笔记--第一章 R语言介绍

    1.典型的数据分析过程可以总结为一下图形: 注意,在模型建立和验证的过程中,可能需要重新进行数据清理和模型建立. 2.R语言一般用 <- 作为赋值运算符,一般不用 = ,原因待考证.用-> ...

  6. 浅谈Visitor Pattern

    第一步:   在介绍Visitor Pattern (访问者模式)之前,先简要介绍一下:双重分派. 在Visitor Pattern中双重分派是指:数据结构的每一个节点都可以接受一个访问者的调用(这句 ...

  7. 物理和虚拟兼容性RDM的区别

    Difference between Physical compatibility RDMs and Virtual compatibility RDMs (2009226) Purpose This ...

  8. vue-cli脚手架的.babelrc文件

    虽然es6还没被浏览器全部支持,但是使用es6是大势所趋,所以babel应运而生将es6代码转换成浏览器能够识别的代码 什么是.babelrc文件呢? 熟悉linux的同学一定知道,rc结尾的文件通常 ...

  9. 我的代码,写的pagebase。还是留着吧。语义化,与我的云平台一样,只不过云平台是用js写的。这个是webform.下回写mvc吧。核心很简单。

    Ps:记一下用的时候,一不小心我手贱碰到的问题吧:我在页面里面加上了form runat=server,然后所有的html控件就再也找不着了.就是下面的control collection这里,如果加 ...

  10. Sqlite 约束条件 Constraints

    一.约束 Constraints 我们在数据库中存储数据的时候,有一些数据有明显的约束条件. 比如一所学校关于教师的数据表,其中的字段列可能有如下约束: 年龄 - 至少大于20岁.如果你想录入一个小于 ...