我在较早时期的一篇文章《
基于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
= newMailMessage(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 inmailInfo.Attachments)
{
mail.Attachments.Add(
newAttachment(fileName));
}
//嵌入资源 AlternateView view =AlternateView.CreateAlternateViewFromString(mailInfo.Body, Encoding.UTF8, MediaTypeNames.Text.Html);foreach (LinkedAttachementInfo link inmailInfo.EmbedObjects)
{
LinkedResource resource
= newLinkedResource(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 = newSmtpClient();
client.Host
=settingInfo.SmtpServer;
client.Port
=settingInfo.SmptPort;
client.UseDefaultCredentials
= false;
client.DeliveryMethod
=SmtpDeliveryMethod.Network;
client.Credentials
= newNetworkCredential(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>
        publicCommonResult Send(MailInfo mailInfo)
{
CommonResult result
= newCommonResult();try{
AppConfig config
= newAppConfig();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, outport);

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

result.Success
=PrivateSendEmail(mailInfo, settingInfo);
}
catch(Exception ex)
{
result.ErrorMessage
=ex.Message;throw;
}
returnresult;
}
/// <summary> ///通用发送邮件操作/// </summary> private static boolPrivateSendEmail(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
= newMailMessage(settingInfo.MailFrom, toEmails);if (!string.IsNullOrEmpty(bcc))
{
mail.Bcc.Add(bcc);
}
if (!string.IsNullOrEmpty(cc))
{
mail.CC.Add(cc);
}
//附件 foreach (string fileName inmailInfo.Attachments)
{
mail.Attachments.Add(
newAttachment(fileName));
}
//嵌入资源 AlternateView view =AlternateView.CreateAlternateViewFromString(mailInfo.Body, Encoding.UTF8, MediaTypeNames.Text.Html);foreach (LinkedAttachementInfo link inmailInfo.EmbedObjects)
{
LinkedResource resource
= newLinkedResource(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 = newSmtpClient();
client.Host
=settingInfo.SmtpServer;
client.Port
=settingInfo.SmptPort;
client.UseDefaultCredentials
= false;
client.DeliveryMethod
=SmtpDeliveryMethod.Network;
client.Credentials
= newNetworkCredential(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);
returnsuccess;
}

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

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

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

        public boolSend()
{
bool sended = false;using (SMTP_Client client = newSMTP_Client())
{
client.Connect(smtpServer, smtpPort, smtpUseSsl);
client.EhloHelo(smtpServer);
var authhh = newAUTH_SASL_Client_Plain(username, password);
client.Auth(authhh);
//client.Authenticate(username, password);//string text = client.GreetingText; client.MailFrom(from, -1);foreach (string address intoList.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 = newMemoryStream())
{
m.ToStream(stream,
newMIME_Encoding_EncodedWord(MIME_EncodedWordEncoding.Q, Encoding.UTF8), Encoding.UTF8);
stream.Position
= 0;
client.SendMessage(stream);

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

client.Disconnect();
}
returnsended;
}

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

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

using (MemoryStream stream = newMemoryStream())
{
m.ToStream(stream,
newMIME_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, stringmailFromDisplay,string subject, string body, Dictionary<string, string> attachments, string notifyEmail = "", string plaintTextTips = "")
{
Mail_Message msg
= newMail_Message();
msg.MimeVersion
= "1.0";
msg.MessageID
=MIME_Utils.CreateMessageID();
msg.Date
=DateTime.Now;
msg.Subject
=subject;
msg.From
= newMail_t_MailboxList();
msg.From.Add(
newMail_t_Mailbox(mailFromDisplay, mailFrom));
msg.To
= newMail_t_AddressList();foreach (string address intomails.Keys)
{
string displayName =tomails[address];
msg.To.Add(
newMail_t_Mailbox(displayName, address));
}
msg.Cc
= newMail_t_AddressList();foreach (string address inccmails.Keys)
{
string displayName =ccmails[address];
msg.Cc.Add(
newMail_t_Mailbox(displayName, address));
}
//设置回执通知 if (!string.IsNullOrEmpty(notifyEmail) &&ValidateUtil.IsEmail(notifyEmail))
{
msg.DispositionNotificationTo.Add(
newMail_t_Mailbox(notifyEmail, notifyEmail));
}
#region MyRegion //--- multipart/mixed ----------------------------------- MIME_h_ContentType contentType_multipartMixed = newMIME_h_ContentType(MIME_MediaTypes.Multipart.mixed);
contentType_multipartMixed.Param_Boundary
= Guid.NewGuid().ToString().Replace('-', '.');
MIME_b_MultipartMixed multipartMixed
= newMIME_b_MultipartMixed(contentType_multipartMixed);
msg.Body
=multipartMixed;//--- multipart/alternative ----------------------------- MIME_Entity entity_multipartAlternative = newMIME_Entity();
MIME_h_ContentType contentType_multipartAlternative
= newMIME_h_ContentType(MIME_MediaTypes.Multipart.alternative);
contentType_multipartAlternative.Param_Boundary
= Guid.NewGuid().ToString().Replace('-', '.');
MIME_b_MultipartAlternative multipartAlternative
= newMIME_b_MultipartAlternative(contentType_multipartAlternative);
entity_multipartAlternative.Body
=multipartAlternative;
multipartMixed.BodyParts.Add(entity_multipartAlternative);
//--- text/plain ---------------------------------------- MIME_Entity entity_text_plain = newMIME_Entity();
MIME_b_Text text_plain
= newMIME_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 = newMIME_Entity();
MIME_b_Text text_html
= newMIME_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 = newWebClient();foreach (string attach inattachments.Keys)
{
try{byte[] bytes =client.DownloadData(attach);using (MemoryStream stream = newMemoryStream(bytes))
{
multipartMixed.BodyParts.Add(Mail_Message.CreateAttachment(stream, attachments[attach]));
}
}
catch(Exception ex)
{
LogTextHelper.Error(ex);
}
}
#endregion returnmsg;
}

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

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

mainEntity.From
= newAddressList();
mainEntity.From.Add(
newMailboxAddress(mailFromDisplay, mailFrom));
mainEntity.To
= newAddressList();
mainEntity.To.Add(
newMailboxAddress(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
= newAddressList();
mainEntity.ReplyTo.Add(
newMailboxAddress(replyEmail, replyEmail));
}

MimeEntity textEntity
=mainEntity.ChildEntities.Add();
textEntity.ContentType
=MediaType_enum.Text_html;
textEntity.ContentTransferEncoding
=ContentTransferEncoding_enum.QuotedPrintable;
textEntity.DataText
=body;//附件 foreach (string attach inattachments)
{
MimeEntity attachmentEntity
=mainEntity.ChildEntities.Add();
attachmentEntity.ContentType
=MediaType_enum.Application_octet_stream;
attachmentEntity.ContentDisposition
=ContentDisposition_enum.Attachment;
attachmentEntity.ContentTransferEncoding
=ContentTransferEncoding_enum.Base64;
FileInfo file
= newFileInfo(attach);
attachmentEntity.ContentDisposition_FileName
=file.Name;
attachmentEntity.DataFromFile(attach);
}
//嵌入图片 foreach (string key inembedImages.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
= newFileInfo(imageFile);
attachmentEntity.ContentDisposition_FileName
=file.Name;//string displayName = Path.GetFileNameWithoutExtension(fileName); attachmentEntity.ContentID = key;//BytesTools.BytesToHex(Encoding.Default.GetBytes(fileName)); attachmentEntity.DataFromFile(imageFile);
}
returnm;
}

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

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

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

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

        private void btnCreateFile_Click(objectsender, 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(objectsender, EventArgs e)
{
using (SMTP_Client client = newSMTP_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
= newMemoryStream();
msg.ToStream(stream,
newMIME_Encoding_EncodedWord(MIME_EncodedWordEncoding.Q, Encoding.UTF8), Encoding.UTF8);
stream.Position
= 0;
client.SendMessage(stream);
client.Disconnect();
}
MessageUtil.ShowTips(
"OK");
}

标签: none

添加新评论