好网站建设公司选择哪家好,什么是网站内链,开封网站优化公司,购物网站建设款流程发起的.NET Core开源组织号召#xff0c;进展的速度是我自己也没有想到的#xff0c;很多园友都积极参与#xff08;虽然有些人诚心砸场子#xff0c;要是以我以前的宝脾气#xff0c;这会应该被我打住院了吧#xff0c;不过幸好是少数#xff0c;做一件事总有人说好进展的速度是我自己也没有想到的很多园友都积极参与虽然有些人诚心砸场子要是以我以前的宝脾气这会应该被我打住院了吧不过幸好是少数做一件事总有人说好也有人说是用武汉话说“闹眼子”.NET社区不是没有乐于共享知识的人只是没有一个完整和良好的生态环境总之希望国内的.NET发展越来越强大。我在这里想到一句话“我们希望自己可以做巨浪但我们也甘愿做巨浪来袭前的小浪”。 上面扯淡完毕我这人干正事前都要将一些扯淡的话这个习惯改不掉了... 项目中为了及时的通信有直接发数据到页面也有利用短信通知也有我门今天介绍的邮件组件。我们今天的主要任务就是讲解一下有一个.NET的免费开源的邮件组件MailKit。本文将一如既往的结合实例和组件底层代码讲解一下相关组件的知识。项目招人的时候我都会问一下.NET的底层原理有一个大神问我这样有什么意义吗我们也写不出.NET底层那样的优秀处理方式为何取了解这些其实我个人觉得问底层的原理只是向为了跟好的处理一些程序出现的问题以及对程序编码的时候选择最合适的方式提升性能任何一种方式都有优势和劣势.NET的类库代码也是如此如果我们知道.NET的底层实现我们在项目的需求实现时可以根据.NET底层实现选择合适的方式以求性能最优。
一.Mailkit组件概述 项目中使用Email的操作机会比较多一般稍微大一点的项目都会使用到邮件操作这一个操作。对于.NET邮件操作的组件和方式比较多今天我们就介绍一款邮件操作的组件MailKit这个邮件组件是一个开源免费的我们现在就来了解一下这一个组件的特点。MimeKit旨在通过尽可能接近地遵循MIME规范来解决这个问题同时还为程序员提供了一个非常容易使用的高级API。 组件的支持的客户端类型比较多例如SMTP客户端、POP3客户端、IMAP客户端。该组件是一个跨平台的Email组件该组件支持.NET 4.0.NET 4.5Xamarin.AndroidXamarin.iOSWindows Phone 8.1等等平台。该组件提供了一个MIME解析器组件具备的解析特性灵活、性能高、很好的处理各种各样的破碎的MIME格式化。MimeKit的性能实际上与GMime相当。 该组件在安全性的还是比较高的处理安全的方式较多SASL认证、支持S / MIME v3.2、支持OpenPGP、支持DKIM签名等等方式。Mailkit组件可以通过CancellationToken取消对应的操作CancellationToken传播应取消操作的通知一个的CancellationToken使线程线程池工作项目之间或取消合作任务的对象。过实例化CancellationTokenSource对象来创建取消令牌该对象管理从其CancellationTokenSource.Token属性检索的取消令牌。然后将取消令牌传递到应该收到取消通知的任意数量的线程任务或操作。令牌不能用于启动取消。 MailKit组件支持异步操作在内部编写的有关I/O异步操作的类。
二.MailKit实例 上面介绍了MailKit组件的背景和特点这里就介绍一下Email组件的简单应用。 1.创建邮件方式
public void SentEmail(string path) { var message new MimeMessage(); //获取From标头中的地址列表添加指定的地址 message.From.Add(new MailboxAddress(Joey, joeyfriends.com)); //获取To头中的地址列表添加指定的地址 message.To.Add(new MailboxAddress(Alice, alicewonderland.com)); //获取或设置消息的主题 message.Subject How you doin?; // 创建我们的消息文本就像以前一样除了不设置为message.Body var body new TextPart(plain) { Text Hey Alice-- Joey }; // 为位于路径的文件创建图像附件 var attachment new MimePart(image, gif) { ContentObject new ContentObject(File.OpenRead(path), ContentEncoding.Default), ContentDisposition new ContentDisposition(ContentDisposition.Attachment), ContentTransferEncoding ContentEncoding.Base64, FileName Path.GetFileName(path) }; // 现在创建multipart / mixed容器来保存消息文本和图像附件 var multipart new Multipart(mixed) { body, attachment }; // 现在将multipart / mixed设置为消息正文 message.Body multipart; } 调用该组件发送邮件和为邮件添加附件是比较简单的第一步是实例化MimeMessage对象对于该对象的解析将在下面进行得到MimeMessage对象后指定邮件的地址和主题等等相关信息。第二步实例化TextPart对象为对象设定文本信息。若需要问邮件创建文件的附件可以使用MimePart对象包含内容如消息正文文本或的叶节点MIME部分一个附件。第四步为创建的邮件主体和文本以及附件信息后可以创建Multipart对象创建邮件容器用来装载文本信息和附件。最后调用MimeMessage.body属性获取或设置消息的正文。 2.邮件信息的解析
var message MimeMessage.Loadstream; 邮件的信息我们需要进行对应的解析这里我们使用MimeMessage的Load方法该方法从指定的流加载MimeKit.MimeMessage。另一个加载数据的方式可以使用MimeParser类这里就不再解析了。 3.邮件的接收
public static void HandleMimeEntity(MimeEntity entity) { //MimeEntity转化为Multipart实体 var multipart entity as Multipart; if (multipart ! null) { for (int i 0; i multipart.Count; i) HandleMimeEntity(multipart[i]); return; } var rfc822 entity as MessagePart; if (rfc822 ! null) { var message rfc822.Message; HandleMimeEntity(message.Body); return; } var part (MimePart)entity; } 以上是对接收到的消息的一个遍历采用递归遍历MIME结构。MIME是内容的树结构很像一个文件系统。MIME确实定义了一组通用规则用于邮件客户端如何解释MIME部分的树结构。的 内容处置头是为了给接收客户端提供提示以哪些部分是为了显示作为消息体的一部分并且意在被解释为附件。另外两种方式这离就不做介绍了。
三.MailKit核心对象解析 上面介绍了Email的基本操作就不做过多的介绍在使用该组件时较为的简单。这里就来看看该组件的类型结构和一些核心对象。类库结构有如下图 1.MimeMessage.Load()
public static MimeMessage Load (ParserOptions options, Stream stream, bool persistent, CancellationToken cancellationToken default (CancellationToken)) { if (options null) throw new ArgumentNullException (nameof (options)); if (stream null) throw new ArgumentNullException (nameof (stream)); var parser new MimeParser (options, stream, MimeFormat.Entity, persistent); return parser.ParseMessage (cancellationToken); } 该方法从指定的流加载MimeMessage具有6个方法重载。该方法返回一个MimeMessage对象有源码可以看出在该方法内部创建了一个MimeParser对象MimeParser包含内容例如邮件正文文本或附件的叶节点MIME部分。调用ParseMessage方法解析来自流的消息。 2.TextPart.Text
public string Text { get { if (ContentObject null) return string.Empty; var charset ContentType.Parameters[charset]; using (var memory new MemoryStream ()) { ContentObject.DecodeTo (memory); var content memory.ToArray (); Encoding encoding null; if (charset ! null) { try { encoding CharsetUtils.GetEncoding (charset); } catch (NotSupportedException) { } } if (encoding null) { try { return CharsetUtils.UTF8.GetString (content, 0, (int) memory.Length); } catch (DecoderFallbackException) { encoding CharsetUtils.Latin1; } } return encoding.GetString (content, 0, (int) memory.Length); } } set { SetText (Encoding.UTF8, value); } } 该属性获取解码的文本内容。该属性是一个可读可写的属性。ContentType.Parameters[charset]用于获取charset参数的值。该方法用来将参数的值设置为数据流并设置对应的编码。看到这里的异常处理结构就想简单的谈几句.NET的异常比较的薄弱很多时候在写.NET的异常时就更加的简单以上是对异常知识捕获有些地方并没有做处理有些地方是对异常的地方进行恢复。 3.MimeEntity.WriteTo()
public virtual void WriteTo (FormatOptions options, Stream stream, bool contentOnly, CancellationToken cancellationToken default (CancellationToken)) { if (options null) throw new ArgumentNullException (nameof (options)); if (stream null) throw new ArgumentNullException (nameof (stream)); if (!contentOnly) Headers.WriteTo (options, stream, cancellationToken); } 该方法将MimeEntity写入到指定的数据流中该方法接受参数options格式选项。stream输出数据流contentOnly判断是否可写。该方法定义为虚方法在继承此方法后可以在子类种对该方法进行重写。
四.总结 本人觉得在项目开发中如果引入了第三方组件我们尽量引入组件的源码这样我们对整个组件的结构有一个认识组件的实现方式我们也可以进行细致了解尤其是我们在进行调试的事后更加有用我们可以逐一的进行断点调试。以上是对该组件的一个简单介绍有兴趣的可以去深入的了解和学习。
原文地址http://www.cnblogs.com/pengze0902/p/6562447.html .NET社区新闻深度好文微信中搜索dotNET跨平台或扫描二维码关注