博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
基于Lumisoft.NET组件和.NET API实现邮件发送功能的对比
阅读量:6375 次
发布时间:2019-06-23

本文共 17903 字,大约阅读时间需要 59 分钟。

我在较早时期的一篇文章《》有大致对这个Lumisoft.NET组件的使用进行了介绍,在《》则对使用.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发送邮件操作的完整代码如下:

///         /// 发送外部邮件(系统配置,系统邮件)        ///         /// 发送邮件信息        /// 
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; } /// /// 通用发送邮件操作 /// 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
tomails, Dictionary
ccmails, string mailFrom, string mailFromDisplay, string subject, string body, Dictionary
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;//"这是一份测试邮件,
来自
LumiSoft.Net"; 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
attachments, Dictionary
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
attachments = new List
(); attachments.Add(attachFile); string subject = "测试邮件"; string body = "这是一份测试邮件,来自
LumiSoft.Net"; string bodyEmbedy = "这是一份测试邮件
,来自
LumiSoft.Net"; Dictionary
embedList = new Dictionary
(); 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");        }

 

转载地址:http://zztqa.baihongyu.com/

你可能感兴趣的文章
eclipse高亮显示
查看>>
Shell 操作数据库
查看>>
if lte IE if gte IE 浏览器兼容
查看>>
基于Lumisoft.NET组件和.NET API实现邮件发送功能的对比
查看>>
C#数据库访问技术之DATAREADER对象读取数据
查看>>
各种排序方法
查看>>
编译时程序透彻理解异常并合理使用异常
查看>>
2013年5月18日星期六
查看>>
js 字符串操作函数集合
查看>>
nullnullCF 312B(Archer-等比数列极限求和)
查看>>
消息函数windows 程序设计 第三章 (下)
查看>>
java中调用web中的jsp或servlet去通知它们做一些操作
查看>>
Javascript 坦克大战
查看>>
JavaScript自动设置IFrame高度(兼容各主流浏览器)
查看>>
Linux内核中__init, __initdata, __initfunc(), asmlinkage, ENTRY(), FASTCALL()等作用
查看>>
leetcode -- Two Sum
查看>>
Windows多线程
查看>>
Resolve PSExec "Access is denied"
查看>>
C语言局部变量和全局变量问题汇总
查看>>
android 下的网络图片加载
查看>>