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

   发起的.NET Core开源组织号召,进展的快慢是作者要好也未曾想到的,非常多园友都积极插足(固然有些人诚心砸场子,纵然以本身在此以前的宝脾性,那会应该被笔者打住院了啊,但是还好是个别,做一件事总有的人说好,也可能有些人会讲是用塞内加尔达喀尔话说“闹眼子”),.NET社区不是平素不愿意大利共产党享文化的人,只是未有一个完好无缺和优良的生态景况,综上说述希望国内的.NET发展更是庞大。作者在此地想到一句话“大家期望自身能够做巨浪,但我们也愿意做巨浪来袭前的小浪”。

   上面扯淡完毕(笔者那人干正事前,都要将一部分摆龙门阵的话,那些习于旧贯改不掉了...)

   项目中为了及时的通讯,有直接发多少到页面,也是有选择短信布告,也是有小编门前些天介绍的邮件组件。我们今日的基本点职务就是上课一下有一个.NET的无偿开源的邮件组件Mail基特。本文将照旧的重组实例和零部件底层代码疏解一下休戚相关组件的文化。(项目招人的时候,我都会问一下.NET的底部原理,有八个大神问笔者这么有哪些含义吗?大家也写不出.NET底层那样的特出管理情势,为啥取了然那一个,其实自身个人以为,问底层的准则,只是向为了跟好的处理局地顺序出现的主题材料,以及对程序编码的时候,选择最合适的措施升高质量,任何一种方法都有优势和劣势,.NET的类库代码也是这么,假设大家知道.NET的底层完成,大家在品种的供给实现时,能够根据.NET底层完毕,采用适宜的方法,以求品质最优)。

一.Mailkit组件概述

   项目中使用Email的操作机遇相当多,常常不怎么大学一年级些的花色,都会选取到邮件操作那八个操作。对于.NET邮件操作的零部件和措施比非常多,明天我们就介绍一款邮件操作的机件MailKit,这么些邮件组件是一个开源免费的,大家前天就来询问一下那四个零件的特点。MimeKit意在通过尽大概临近地服从MIME标准来缓和这么些问题,相同的时候还为程序猿提供了二个极度轻便使用的高档次和等第API。

   组件的支撑的客商端类型较多,举个例子SMTP客户端、POP3顾客端、IMAP顾客端。该器件是叁个跨平台的Email组件,该零件帮忙.NET 4.0,.NET 4.5,Xamarin.Android,Xamarin.iOS,Windows Phone 8.1等等平台。该器件提供了三个MIME分析器,组件具有的剖析本性灵活、品质高、很好的拍卖长短不一的破碎的MIME格式化。MimeKit的性情实际上与丙胺搏来霉素ime万分。

   该零件在安全性的依旧相比高的,处理平安的办法比较多,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", "joey@friends.com"));
            //获取To头中的地址列表,添加指定的地址
            message.To.Add(new MailboxAddress("Alice", "alice@wonderland.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.Load(stream);

   邮件的消息大家须要张开对应的分析,这里大家使用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部分的树结构。的 内容处置头是为着给接受客户端提供提示以什么样部分是为了展现作为新闻体的一有的,而且意在被分解为附属类小部件。别的两种格局那离就不做牵线了。

三.Mail基特宗旨对象深入分析

   上边介绍了Email的基本操作就不做过多的牵线,在选拔该器件时,较为的简短。这里就来会见该零件的品类结商谈一部分主干指标。类库结构有如下图:

图片 1

    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推断是或不是可写。该措施定义为虚方法,在持续此措施后,能够在子类种对该格局开展重写。

四.总结

   本人以为在品种开采中,如若引进了第三方组件,我们尽量引进组件的源码,那样我们对整体组件的结构有多少个认识,组件的兑现方式咱们也足以开展密切明白,极其是咱们在开展调治的之后尤其有用,大家得以逐个的扩充断点调试。以上是对该器件的四个粗略介绍,风乐趣的能够去深远的打听和读书。

本文由88必发唯一官网必发布于办公软件,转载请注明出处:跨平台的.NET邮件协议MailKit组件解析

相关阅读