基于Lumisoft.NET组件和.NET API实现邮件发送功能的对比

简介:

我在较早时期的一篇文章《基于Lumisoft.NET实现的邮件发送功能》有大致对这个Lumisoft.NET组件的使用进行了介绍,在《DevExpress控件使用之RichEditControl的使用》则对使用.NET API进行邮件发送进行了说明,其实,实现邮件发送,这两种方式是比较常见的,当然Lumisoft.NET组件除了提供邮件发送功能外,还提供了邮件接收等功能的处理(包括基于POP3协议和IMAP协议),而.NET则除了提供SMTP协议功能外,则没有提供POP3协议处理的相关类库,因此收取邮件这需要自己进行封装(需要也可以参考codeproject.com上的相关文章)。

1、.NET的邮件发送功能实现

.NET本身封装了一个SmtpClient类以及相关的邮件对象类,这样利用这些类库,也可以方便实现邮件的发送功能的了。

如添加发送人地址,抄送地址,以及暗送地址(多个地址用逗号分开)代码如下。

            string toEmails = mailInfo.ToEmail;
            
            string bcc = "";
            mailInfo.RecipientBCC.ForEach(obj => bcc += string.Format("{0},", obj));
            bcc = bcc.Trim(',');

            string cc = "";
            mailInfo.RecipientCC.ForEach(obj => cc += string.Format("{0},", obj));
            cc = cc.Trim(',');

            MailMessage mail = new MailMessage(settingInfo.MailFrom, toEmails);
            if (!string.IsNullOrEmpty(bcc))
            {
                mail.Bcc.Add(bcc);
            }
            if (!string.IsNullOrEmpty(cc))
            {
                mail.CC.Add(cc);
            }

.NET的附件和嵌入式资源由对象Attachment和LinkedResource进行管理,他们的利用代码如下所示:

            //附件
            foreach (string fileName in mailInfo.Attachments)
            {
                mail.Attachments.Add(new Attachment(fileName));
            }

            //嵌入资源
            AlternateView view = AlternateView.CreateAlternateViewFromString(mailInfo.Body, Encoding.UTF8, MediaTypeNames.Text.Html);
            foreach (LinkedAttachementInfo link in mailInfo.EmbedObjects)
            {
                LinkedResource resource = new LinkedResource(link.Stream, link.MimeType);
                resource.ContentId = link.ContentId;
                view.LinkedResources.Add(resource);
            }
            mail.AlternateViews.Add(view);

发送邮件的其他部分代码如下所示

            mail.IsBodyHtml = mailInfo.IsBodyHtml;
            mail.BodyEncoding = Encoding.UTF8;
            mail.Subject = mailInfo.Subject;
            mail.SubjectEncoding = Encoding.UTF8;

            //发送账户设置信息
            SmtpClient client = new SmtpClient();
            client.Host = settingInfo.SmtpServer;
            client.Port = settingInfo.SmptPort;
            client.UseDefaultCredentials = false;
            client.DeliveryMethod = SmtpDeliveryMethod.Network;
            client.Credentials = new NetworkCredential(settingInfo.SmtpUser, settingInfo.SmtpPass);

            bool success = false;
            try
            {
                client.Send(mail);
                success = true;
            }
            catch (Exception ex)
            {
                LogTextHelper.Error(ex);
                //throw;
            }

上面利用.net的SmtpClient发送邮件操作的完整代码如下:

        /// <summary>
        /// 发送外部邮件(系统配置,系统邮件)
        /// </summary>
        /// <param name="mailInfo">发送邮件信息</param>
        /// <returns></returns>
        public CommonResult Send(MailInfo mailInfo)
        {
            CommonResult result = new CommonResult();
            try
            {
                AppConfig config = new AppConfig();
                string MailDomain = config.AppConfigGet("MailDomain");
                string MailUsername = config.AppConfigGet("MailUsername");
                string MailPassword = config.AppConfigGet("MailPassword");
                string MailPort = config.AppConfigGet("MailPort");
                string MailFrom = config.AppConfigGet("MailFrom");
                int port = 25;
                int.TryParse(MailPort, out port);

                SmtpSettingInfo settingInfo = new SmtpSettingInfo(MailDomain, port,
                    MailUsername, MailPassword, MailFrom);

                result.Success = PrivateSendEmail(mailInfo, settingInfo);
            }
            catch (Exception ex)
            {
                result.ErrorMessage = ex.Message;
                throw;
            }

            return result; 
        }

        /// <summary>
        /// 通用发送邮件操作
        /// </summary>
        private static bool PrivateSendEmail(MailInfo mailInfo, SmtpSettingInfo settingInfo)
        {          
            string toEmails = mailInfo.ToEmail;
            
            string bcc = "";
            mailInfo.RecipientBCC.ForEach(obj => bcc += string.Format("{0},", obj));
            bcc = bcc.Trim(',');

            string cc = "";
            mailInfo.RecipientCC.ForEach(obj => cc += string.Format("{0},", obj));
            cc = cc.Trim(',');

            MailMessage mail = new MailMessage(settingInfo.MailFrom, toEmails);
            if (!string.IsNullOrEmpty(bcc))
            {
                mail.Bcc.Add(bcc);
            }
            if (!string.IsNullOrEmpty(cc))
            {
                mail.CC.Add(cc);
            }

            //附件
            foreach (string fileName in mailInfo.Attachments)
            {
                mail.Attachments.Add(new Attachment(fileName));
            }

            //嵌入资源
            AlternateView view = AlternateView.CreateAlternateViewFromString(mailInfo.Body, Encoding.UTF8, MediaTypeNames.Text.Html);
            foreach (LinkedAttachementInfo link in mailInfo.EmbedObjects)
            {
                LinkedResource resource = new LinkedResource(link.Stream, link.MimeType);
                resource.ContentId = link.ContentId;
                view.LinkedResources.Add(resource);
            }
            mail.AlternateViews.Add(view);
            mail.IsBodyHtml = mailInfo.IsBodyHtml;
            mail.BodyEncoding = Encoding.UTF8;
            mail.Subject = mailInfo.Subject;
            mail.SubjectEncoding = Encoding.UTF8;

            //发送账户设置信息
            SmtpClient client = new SmtpClient();
            client.Host = settingInfo.SmtpServer;
            client.Port = settingInfo.SmptPort;
            client.UseDefaultCredentials = false;
            client.DeliveryMethod = SmtpDeliveryMethod.Network;
            client.Credentials = new NetworkCredential(settingInfo.SmtpUser, settingInfo.SmtpPass);

            bool success = false;
            try
            {
                client.Send(mail);
                success = true;
            }
            catch (Exception ex)
            {
                LogTextHelper.Error(ex);
                //throw;
            }

            string message = string.Format("发送给【{0}】的邮件“{1}”,{2},时间:{3}",
                mailInfo.ToEmail[0], mailInfo.Subject, success ? "发送成功" : "发送失败", DateTime.Now);
            LogTextHelper.Info(message);

            return success;
        }

2、基于Lumisoft.NET组件的邮件发送功能实现

基于Lumisoft.NET组件的邮件发送,也是一种很常用的,因为这个开源组件非常强大,经常可以在一些程序中被使用。

这个发送邮件的功能主要是利用SMTP_Client类来实现的,如下代码所示。注意其中的Authenticate函数已经被舍弃,可以使用Auth方法进行验证。但是函数参数有所不同,根据验证对象,使用不同的验证方式,一般选择AUTH_SASL_Client_Plain对象即可。

        public bool Send()
        {
            bool sended = false;
            using (SMTP_Client client = new SMTP_Client())
            {
                client.Connect(smtpServer, smtpPort, smtpUseSsl);
                client.EhloHelo(smtpServer);
                var authhh = new AUTH_SASL_Client_Plain(username, password);
                client.Auth(authhh);
                //client.Authenticate(username, password);
                //string text = client.GreetingText;
                client.MailFrom(from, -1);
                foreach (string address in toList.Keys)
                {
                    client.RcptTo(address);
                }

                //采用Mail_Message类型的Stream
                Mail_Message m = Create_PlainText_Html_Attachment_Image(toList, ccList, from, fromDisplay, subject, body, attachments);
                using (MemoryStream stream = new MemoryStream())
                {
                    m.ToStream(stream, new MIME_Encoding_EncodedWord(MIME_EncodedWordEncoding.Q, Encoding.UTF8), Encoding.UTF8);
                    stream.Position = 0;
                    client.SendMessage(stream);

                    sended = true;
                }
                if (m != null)
                {
                    m.Dispose();
                }

                client.Disconnect();
            }
            return sended;
        }

构造用于SMTP发送的数据,可以使用Mail_Message 对象,也可以使用Mime对象,虽然读都可以实现发送功能,不过Mime对象是舍弃的对象了。

构造Mail_Message对象后,创建用于发送的格式要转换为Stream对象。转换为发送的Stream操作如下所示。

using (MemoryStream stream = new MemoryStream())
{
        m.ToStream(stream, new MIME_Encoding_EncodedWord(MIME_EncodedWordEncoding.Q, Encoding.UTF8), Encoding.UTF8);
        stream.Position = 0;
        client.SendMessage(stream);

        sended = true;
 }

构造Mail_Message格式的邮件操作如下所示。

        private Mail_Message Create_PlainText_Html_Attachment_Image(Dictionary<string,string> tomails, Dictionary<string, string> ccmails, string mailFrom, string mailFromDisplay,
            string subject, string body, Dictionary<string, string> attachments, string notifyEmail = "", string plaintTextTips = "")
        {
            Mail_Message msg = new Mail_Message();
            msg.MimeVersion = "1.0";
            msg.MessageID = MIME_Utils.CreateMessageID();
            msg.Date = DateTime.Now;
            msg.Subject = subject;
            msg.From = new Mail_t_MailboxList();
            msg.From.Add(new Mail_t_Mailbox(mailFromDisplay, mailFrom));
            msg.To = new Mail_t_AddressList();
            foreach (string address in tomails.Keys)
            {
                string displayName = tomails[address];
                msg.To.Add(new Mail_t_Mailbox(displayName, address));
            }
            msg.Cc = new Mail_t_AddressList();
            foreach (string address in ccmails.Keys)
            {
                string displayName = ccmails[address];
                msg.Cc.Add(new Mail_t_Mailbox(displayName, address));
            }            

            //设置回执通知
            if (!string.IsNullOrEmpty(notifyEmail) && ValidateUtil.IsEmail(notifyEmail))
            {
                msg.DispositionNotificationTo.Add(new Mail_t_Mailbox(notifyEmail, notifyEmail));
            }

            #region MyRegion

            //--- multipart/mixed -----------------------------------
            MIME_h_ContentType contentType_multipartMixed = new MIME_h_ContentType(MIME_MediaTypes.Multipart.mixed);
            contentType_multipartMixed.Param_Boundary = Guid.NewGuid().ToString().Replace('-', '.');
            MIME_b_MultipartMixed multipartMixed = new MIME_b_MultipartMixed(contentType_multipartMixed);
            msg.Body = multipartMixed;

            //--- multipart/alternative -----------------------------
            MIME_Entity entity_multipartAlternative = new MIME_Entity();
            MIME_h_ContentType contentType_multipartAlternative = new MIME_h_ContentType(MIME_MediaTypes.Multipart.alternative);
            contentType_multipartAlternative.Param_Boundary = Guid.NewGuid().ToString().Replace('-', '.');
            MIME_b_MultipartAlternative multipartAlternative = new MIME_b_MultipartAlternative(contentType_multipartAlternative);
            entity_multipartAlternative.Body = multipartAlternative;
            multipartMixed.BodyParts.Add(entity_multipartAlternative);

            //--- text/plain ----------------------------------------
            MIME_Entity entity_text_plain = new MIME_Entity();
            MIME_b_Text text_plain = new MIME_b_Text(MIME_MediaTypes.Text.plain);
            entity_text_plain.Body = text_plain;

            //普通文本邮件内容,如果对方的收件客户端不支持HTML,这是必需的
            string plainTextBody = "如果你邮件客户端不支持HTML格式,或者你切换到“普通文本”视图,将看到此内容";
            if (!string.IsNullOrEmpty(plaintTextTips))
            {
                plainTextBody = plaintTextTips;
            }

            text_plain.SetText(MIME_TransferEncodings.QuotedPrintable, Encoding.UTF8, plainTextBody);
            multipartAlternative.BodyParts.Add(entity_text_plain);

            //--- text/html -----------------------------------------
            string htmlText = body;//"<html>这是一份测试邮件,<img src=\"cid:test.jpg\">来自<font color=red><b>LumiSoft.Net</b></font></html>";
            MIME_Entity entity_text_html = new MIME_Entity();
            MIME_b_Text text_html = new MIME_b_Text(MIME_MediaTypes.Text.html);
            entity_text_html.Body = text_html;
            text_html.SetText(MIME_TransferEncodings.QuotedPrintable, Encoding.UTF8, htmlText);
            multipartAlternative.BodyParts.Add(entity_text_html);

            //--- application/octet-stream -------------------------
            WebClient client = new WebClient();
            foreach (string attach in attachments.Keys)
            {
                try
                {
                    byte[] bytes = client.DownloadData(attach);
                    using (MemoryStream stream = new MemoryStream(bytes))
                    {
                        multipartMixed.BodyParts.Add(Mail_Message.CreateAttachment(stream, attachments[attach]));
                    }
                }
                catch (Exception ex)
                {
                    LogTextHelper.Error(ex);
                }
            }

            #endregion

            return msg;
        }

而构造Mime格式的操作如下所示。

        private Mime Create_Html_Attachment_Image(string mailTo, string mailFrom, string mailFromDisplay,
            string subject, string body, List<string> attachments, Dictionary<string, string> embedImages, string notifyEmail = "", string plaintTextTips = "",
            string replyEmail = "")
        {
            Mime m = new Mime();
            MimeEntity mainEntity = m.MainEntity;

            mainEntity.From = new AddressList();
            mainEntity.From.Add(new MailboxAddress(mailFromDisplay, mailFrom));
            mainEntity.To = new AddressList();
            mainEntity.To.Add(new MailboxAddress(mailTo, mailTo));
            mainEntity.Subject = subject;
            mainEntity.ContentType = MediaType_enum.Multipart_mixed;

            //设置回执通知
            if (!string.IsNullOrEmpty(notifyEmail) && ValidateUtil.IsEmail(notifyEmail))
            {
                mainEntity.DSN = notifyEmail;
            }

            //设置统一回复地址
            if (!string.IsNullOrEmpty(replyEmail) && ValidateUtil.IsEmail(replyEmail))
            {
                mainEntity.ReplyTo = new AddressList();
                mainEntity.ReplyTo.Add(new MailboxAddress(replyEmail, replyEmail));
            }

            MimeEntity textEntity = mainEntity.ChildEntities.Add();
            textEntity.ContentType = MediaType_enum.Text_html;
            textEntity.ContentTransferEncoding = ContentTransferEncoding_enum.QuotedPrintable;
            textEntity.DataText = body;

            //附件
            foreach (string attach in attachments)
            {
                MimeEntity attachmentEntity = mainEntity.ChildEntities.Add();
                attachmentEntity.ContentType = MediaType_enum.Application_octet_stream;
                attachmentEntity.ContentDisposition = ContentDisposition_enum.Attachment;
                attachmentEntity.ContentTransferEncoding = ContentTransferEncoding_enum.Base64;
                FileInfo file = new FileInfo(attach);
                attachmentEntity.ContentDisposition_FileName = file.Name;
                attachmentEntity.DataFromFile(attach);
            }

            //嵌入图片
            foreach (string key in embedImages.Keys)
            {
                MimeEntity attachmentEntity = mainEntity.ChildEntities.Add();
                attachmentEntity.ContentType = MediaType_enum.Application_octet_stream;
                attachmentEntity.ContentDisposition = ContentDisposition_enum.Inline;
                attachmentEntity.ContentTransferEncoding = ContentTransferEncoding_enum.Base64;
                string imageFile = embedImages[key];
                FileInfo file = new FileInfo(imageFile);
                attachmentEntity.ContentDisposition_FileName = file.Name;

                //string displayName = Path.GetFileNameWithoutExtension(fileName);
                attachmentEntity.ContentID = key;//BytesTools.BytesToHex(Encoding.Default.GetBytes(fileName));

                attachmentEntity.DataFromFile(imageFile);
            }

            return m;
        }

综合以上两者的发送功能,都可以实现邮件的发送操作,如下界面是发送邮件界面。

3、LumiSoft.NET存储eml邮件文件以及发送eml文件操作

除了上面的发送普通邮件,Lumisoft还支持吧邮件序列号存储到文件(.eml邮件文件)里面,然后也可以通过把文件读取到流里面,进行发送,对于某种场合,可以把邮件存储到eml文件是一个很好的操作。

存储EML文件的相关操作如下所示。

        private void btnCreateFile_Click(object sender, EventArgs e)
        {
            string attachFile = Path.Combine(Application.StartupPath, "Attachment/Hotel2.png");
            List<string> attachments = new List<string>();
            attachments.Add(attachFile);
            string subject = "测试邮件";
            string body = "<html>这是一份测试邮件,来自<font color=red><b>LumiSoft.Net</b></font></html>";
            string bodyEmbedy = "<html>这是一份测试邮件<img src=\"cid:test.jpg\">,来自<font color=red><b>LumiSoft.Net</b></font></html>";
            Dictionary<string, string> embedList = new Dictionary<string, string>();
            embedList.Add("test.jpg", "C:\\test.jpg");

            //存储为Eml文件
            string path = Path.Combine(Application.StartupPath, "Eml");
            DirectoryUtil.AssertDirExist(path);
            string emlFile = string.Format("{0}/{1}.eml", path, DateTime.Now.ToFileTime());

            Mime m = Create_Html_Attachment_Image(to, from, from, subject, bodyEmbedy, attachments, embedList);
            m.ToFile(emlFile);

            MessageUtil.ShowTips("OK");
        }

发送EML文件操作如下所示。

        private void btnSendFile_Click(object sender, EventArgs e)
        {
            using (SMTP_Client client = new SMTP_Client())
            {
                int smtpPort = smtpUseSsl ? WellKnownPorts.SMTP_SSL : WellKnownPorts.SMTP;

                client.Connect(smtpServer, smtpPort, smtpUseSsl);
                client.EhloHelo(smtpServer);
                //var authhh = new AUTH_SASL_Client_Plain(username, password);
                //client.Auth(authhh);
                client.Authenticate(username, password);
                //string text = client.GreetingText;
                client.MailFrom(from, -1);
                client.RcptTo(to);

                string path = Path.Combine(Application.StartupPath, "Eml");
                string emlFile = Directory.GetFiles(path)[0];
                var msg = Mail_Message.ParseFromFile(emlFile);

                MemoryStream stream = new MemoryStream();
                msg.ToStream(stream, new MIME_Encoding_EncodedWord(MIME_EncodedWordEncoding.Q, Encoding.UTF8), Encoding.UTF8);
                stream.Position = 0;
                client.SendMessage(stream);
                client.Disconnect();
            }
            MessageUtil.ShowTips("OK");
        }

 本文转自博客园伍华聪的博客,原文链接:基于Lumisoft.NET组件和.NET API实现邮件发送功能的对比,如需转载请自行联系原博主。



目录
相关文章
|
7天前
|
定位技术 API C#
.NET开源、功能强大、跨平台的图表库
.NET开源、功能强大、跨平台的图表库
|
11天前
|
存储 缓存 安全
API在Visual Basic中的应用:连接外部服务与扩展功能
【4月更文挑战第27天】本文探讨了在Visual Basic中使用API连接外部服务和扩展功能的方法,涵盖了API的基本概念、种类及如何使用本地和Web API。通过DllImport调用本地API,利用HttpClient和WebClient与Web API交互,同时强调了第三方API的使用和SOA架构中的API角色。安全性、性能优化和错误处理是实践中的关键点。案例研究和最佳实践有助于开发者更有效地利用API,提升Visual Basic应用程序的功能和灵活性。随着API技术的发展,Visual Basic将持续支持开发者创造更强大的应用。
|
9天前
|
人工智能 开发框架 .NET
【专栏】解密.NET 技术的强大功能
【4月更文挑战第29天】这篇文章探讨了.NET技术的关键特性,如多语言支持、统一运行时、丰富的类库和跨平台能力,以及其在企业应用、Web开发、移动应用和游戏开发中的应用。文章指出,.NET正通过性能优化、容器化支持、AI整合和开源策略适应未来软件开发需求,强调了开发者应掌握.NET技术并参与社区,共同推动技术发展。
|
9天前
|
SQL 数据管理 API
数据管理DMS产品使用合集之阿里云DMS提供API接口来进行数据导出功能吗
阿里云数据管理DMS提供了全面的数据管理、数据库运维、数据安全、数据迁移与同步等功能,助力企业高效、安全地进行数据库管理和运维工作。以下是DMS产品使用合集的详细介绍。
|
13天前
|
Java API PHP
邮件发送API的方法和步骤
邮件发送API能便捷地自动化发送邮件,提高效率。步骤包括:1. 选择如aoksend、Mailgun或Amazon SES等适合的API;2. 注册并获取API密钥;3. 设置发件人、收件人、主题和内容等参数;4. 根据API文档用Python等语言编写调用代码;5. 调用API发送邮件并处理结果;6. 根据返回信息判断发送是否成功。适用于大量邮件发送场景。
|
13天前
|
API 开发者
邮件API接口使用的方法和步骤
AOKSEND指南:了解和使用邮件API接口,包括选择适合的接口(如AOKSEND、Mailgun、SMTP),获取访问权限,配置发件人、收件人及邮件内容,调用接口发送邮件,并处理返回结果,以高效集成邮件功能。
|
15天前
|
API PHP 数据安全/隐私保护
IMAP邮箱API接收收取邮件的方法和步骤
IMAP邮箱API是用于自动接收和管理邮件的接口,允许程序无须手动登录即可操作邮件。要使用它,需先配置邮箱允许API访问,选择如Python的imaplib或PHP的imap扩展等IMAP库,然后连接到邮箱服务器,接收和处理邮件。处理完毕后断开连接。AokSend提供高效发信服务,支持SMTP/API接口。使用IMAP API能提升邮件管理效率。
|
15天前
|
API 网络安全 数据安全/隐私保护
SMTP邮件邮箱API发送邮件的方法和步骤
使用SMTP邮件邮箱API(如AokSend)发送邮件涉及6个步骤:获取SMTP服务器地址和端口,进行身份验证,构建邮件内容,连接到服务器,发送邮件及处理结果。例如,Gmail的SMTP服务器地址是smtp.gmail.com,端口587。此方法适用于程序化发送邮件,确保安全并支持大规模发信服务。
|
16天前
|
API Python
Relay邮件邮箱API发送邮件的方法和步骤
Relay邮件邮箱API是编程发送邮件的工具,允许用户通过代码实现邮件发送。发送步骤包括:获取API密钥、设置发件人和收件人信息、编写邮件内容,最后调用API发送。Python示例代码展示了如何使用API发送邮件,需替换API密钥和邮箱地址。
|
16天前
|
监控 API 开发工具
邮件中继中转邮箱API发送邮件的方法和步骤
AokSend介绍了使用邮件中继中转邮箱API发送邮件的步骤:理解API概念,获取API密钥,设置发件人和收件人信息,构建并发送API请求,处理响应,监控调试,及完善邮件功能。该服务支持大量验证码发送、触发式接口和高触达SMTP/API接口。选择合适提供商并参考文档可优化邮件发送。