好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

基于Lumisoft.NET组件的POP3邮件接收和删除操作

基于Lumisoft.NET组件的POP3邮件接收和删除操作

基于Lumisoft.NET组件的POP3邮件接收和删除操作

Lumisoft.NET组件是一个非常强大的邮件发送、邮件接收等功能的开源组件,一般用它来处理邮件的相关操作,是非常合适的。之前也写过一些该组件的随笔文章,不过主要是利用来发送邮件居多,最近由于项目需要,需要利用该组件来接收邮件,邮件通过POP3协议进行接收到本地,故对该组件进行了全面的了解和使用。本文主要是在此背景上,介绍该组件的POP3协议处理类的使用。Lumisoft.NET组件2013年作者有做了一定的更新,修复了一些问题,本文是基于该组件的最新版本进行开发使用。

1、POP3登录及头部信息获取

首先使用POP3,必须创建一个POP3_Client的对象,然后通过Connect和Login进行连接和登录处理,相关的代码如下所示。

             using  (POP3_Client popClient =  new   POP3_Client())
            {
                popClient.Logger  =  new   Logger();
                popClient.Logger.WriteLog  +=  new  EventHandler<WriteLogEventArgs> (WriteLog);

                popClient.Connect(pop3Server, pop3Port, pop3UseSsl);
                popClient.Login(username, password); 

POP3的的邮件下载通过 POP3_Client  对象的属性 Messages对象进行,每个POP3_ClientMessage代表一份完整的邮件信息,一开始应该是只是获取一些简单的邮件信息(其中包括邮件的唯一标识UID),这样才能提高POP3协议的处理速度,如下代码所示。

 foreach  (POP3_ClientMessage message  in  popClient.Messages)

为了进一步获取邮件头部信息,那么需要进行下面的转换

Mail_Message mime_header = Mail_Message.ParseFromByte(message.HeaderToByte());

转换后Mail_Message承载了邮件头部文件的很多必备信息,如发送人,发送人名称,接收地址,抄送人地址,邮件标题,邮件日期等等信息。

这些邮件地址的信息,都是通过Mail_t_Mailbox对象来记录,一般包含邮件地址的Address和显示名称DisplayName,这样非常方便用来显示,如我们可以进行转义,记录到数据库里面。

                         if  (mime_header.From !=  null  )
                        {
                              //  伍华聪(wuhuacong@163测试数据) 
                             string  displayname = mime_header.From[ 0  ].DisplayName;
                              string   from  = mime_header.From[ 0 ].Address; //   DecodeString(mime_header.From[0].Address); 
                             if  (! string  .IsNullOrEmpty(displayname))
                            {
                                info.From  =  string .Format( "  {0}({1})  " , displayname,  from  );
                            }
                              else  
                            {
                                info.From  =  string .Format( "  {0}  " ,  from  );
                            }
                        } 

                         if  (mime_header.To !=  null  )
                        {
                            StringBuilder sb  =  new   StringBuilder();
                              foreach  (Mail_t_Mailbox recipient  in   mime_header.To.Mailboxes)
                            {
                                  string  displayname =  recipient.DisplayName;
                                  string  address =  recipient.Address;
                                  if  (! string  .IsNullOrEmpty(displayname))
                                {
                                    sb.AppendFormat(  "  {0}({1});  "  , displayname, address);
                                }
                                  else  
                                {
                                    sb.AppendFormat(  "  {0};  "  , address);
                                }
                            }
                            info.Senders  = sb.ToString().Trim( '  ;  '  );
                        }

                          if  (mime_header.Cc !=  null  )
                        {
                            StringBuilder sb  =  new   StringBuilder();
                              foreach  (Mail_t_Mailbox recipient  in   mime_header.Cc.Mailboxes)
                            {
                                  string  displayname =  recipient.DisplayName;
                                  string  address =  recipient.Address;
                                  if  (! string  .IsNullOrEmpty(displayname))
                                {
                                    sb.AppendFormat(  "  {0}({1});  "  , displayname, address);
                                }
                                  else  
                                {
                                    sb.AppendFormat(  "  {0};  "  , address);
                                }
                            }
                            info.Carboncopy  = sb.ToString().Trim( '  ;  '  );
                        } 

每封Email会有一个在Pop3服务器范围内唯一的Id,检查这个Id是否存在就可以知道以前有没有接收过这封邮件

info.MailUid = message.UID;

每份邮件的头部信息,都会包含一个日期的,如下可以获取到该日期

info.Date = mime_header.Date;

标题信息可以通过下面代码获取

info.Title = mime_header.Subject;/

2、邮件正文信息和附件信息的获取

如果需要进一步获取邮件的正文内容,则需要对信息进行进一步的转换,把message对象进行MessageToByte操作,然后利用函数Mail_Message.ParseFromByte进行转换。

 byte [] messageBytes =  message.MessageToByte();

Mail_Message mime_message  =  Mail_Message.ParseFromByte(messageBytes);
  if  (mime_message ==  null )  continue  ;
info.Body = mime_message.BodyText; try { if (! string .IsNullOrEmpty(mime_message.BodyHtmlText)) { info.Body = mime_message.BodyHtmlText; } } catch { // 屏蔽编码出现错误的问题,错误在BodyText存在而BodyHtmlText不存在的时候,访问BodyHtmlText会出现 }

邮件的附件是通过MIME_Entity来承载信息的,所以我们需要把对象通过mime_message.GetAttachments(true, true)进行获取,转换为附件信息。

                         #region  邮件附件内容
                         foreach  (MIME_Entity entity  in  mime_message.GetAttachments( true ,  true  ))
                        {
                              if  (entity.ContentDisposition !=  null  && 
                                entity.ContentDisposition.Param_FileName  !=  null  )
                            {
                                  //  Console.WriteLine("Attachment: " + entity.ContentDisposition.Param_FileName); 
                                 string  fileName = entity.ContentDisposition.Param_FileName;

如果需要进一步获取附件里面的文件字节流,那么还需要进行进一步的转换为MIME_b_SinglepartBase对象。

 MIME_b_SinglepartBase byteObj =  (MIME_b_SinglepartBase)entity.Body;
   if  (byteObj !=  null  )
 {
         FileUtil.CreateFile(filePath, byteObj.Data);
         fileSize  = byteObj.Data.Length;

如果要区分邮件里面的附件是内嵌图片附件还是真正的附件,那么可以通过下面代码进行判断,如果是MIME_DispositionTypes.Attachment的就是普通附件,MIME_DispositionTypes.Inline的就是内嵌正文的附件。

entity.ContentDisposition.DispositionType == MIME_DispositionTypes.Attachment

3、邮件的删除操作

 

服务器上的邮件,可以通过POP3的协议方式进行删除,删除操作很简单,主要是通过mail.MarkForDeletion进行标识即可,实例操作代码如下所示

             using  (POP3_Client c =  new   POP3_Client())
            {
                c.Connect(pop3Server, pop3Port, pop3UseSsl);
                c.Login(username, password);

                  if  (c.Messages.Count >  0  )
                {
                      foreach  (POP3_ClientMessage mail  in   c.Messages)
                    {
                          try  
                        {
                              if   (toDeleteMailUidList.Contains(mail.UID))
                            {
                                mail.MarkForDeletion();

                                deletedList.Add(mail.UID);
                            }
                        }
                          catch   (Exception ex)
                        {
                            LogTextHelper.Error(ex);
                        }
                    }
                }
            } 

主要研究技术:代码生成工具、Visio二次开发、送水管理软件等共享软件开发
专注于 Winform开发框架 、WCF开发框架的研究及应用。
  转载请注明出处:
撰写人:伍华聪   http://HdhCmsTestiqidi测试数据  
    

 

 

标签:  开发辅助

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

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

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  "  );
        } 

主要研究技术:代码生成工具、Visio二次开发、送水管理软件等共享软件开发
专注于 Winform开发框架 、WCF开发框架的研究及应用。
  转载请注明出处:
撰写人:伍华聪   http://HdhCmsTestiqidi测试数据  
    

 

 

标签:  开发辅助

基于Lumisoft.NET组件开发碰到乱码等一些问题的解决

在Lumisoft.NET组件获取POP3邮件的时候,发现大多数邮件都能正常获取,不过对于一些特殊的邮件,好像总是会出现转换错误,或者出现乱码及部分乱码现象,有些在标题里面或者邮件接收人地址,而有些则在内容里面,为了更好整理相关的问题,写了本文,希望对大家使用该组件有一定的帮助作用。

1、  日期转换出错问题。

错误信息: [2013-05-04 10:49:03]    转换邮件的Date出错:账号wuhuacong@163测试数据 邮件标题:ICP???????????????????????wuhuacong)

LumiSoft.Net.ParseException: Header field 'Date' parsing failed.

   在 LumiSoft.Net.Mail.Mail_Message.get_Date()

错误原因: 由于邮件格式的日期内容格式不同,导致无法正常解析。如一般的格式为下面

Message-ID: <d74841c5887b4df692ebdb7ec7802054@4782e72954a24cc89535840ea2e5da5b> 
Date: Fri,   26  Apr  2013   08 : 56 : 52   GMT
Mime -Version:  1.0  
From:   "  wuhuacong2013@163测试数据  "  <wuhuacong2013@ 163 测试数据> 
To:   "  wuhuacong@96900测试数据.cn  "  <wuhuacong@ 96900 测试数据.cn>

有些邮件日期格式是2013-05-06 19:01:44,则Lumisoft组件无法解析,需要跟踪到他的邮件日期处理的代码,然后进行修改才可以实现正常的邮件日期解析了。

官方的代码如下所示。

         public   DateTime Date
        {
              get  {
                  if ( this  .IsDisposed){
                      throw   new  ObjectDisposedException( this  .GetType().Name);
                }

                MIME_h h  =  this .Header.GetFirst( "  Date  "  );
                  if (h !=  null  ){
                      try  {
                          return   MIME_Utils.ParseRfc2822DateTime(((MIME_h_Unstructured)h).Value);
                    }
                      catch  {
                          throw   new  ParseException( "  Header field 'Date' parsing failed.  "  );
                    }
                }
                  else  {
                      return   DateTime.MinValue;
                }
            }

              set  {
                  if ( this  .IsDisposed){
                      throw   new  ObjectDisposedException( this  .GetType().Name);
                }
                
                  if (value ==  DateTime.MinValue){
                      this .Header.RemoveAll( "  Date  "  );
                }
                  else  {
                    MIME_h h  =  this .Header.GetFirst( "  Date  "  );
                      if (h ==  null  ){
                          this .Header.Add( new  MIME_h_Unstructured( "  Date  "  ,MIME_Utils.DateTimeToRfc2822(value)));
                    }
                      else  {
                          this .Header.ReplaceFirst( new  MIME_h_Unstructured( "  Date  "  ,MIME_Utils.DateTimeToRfc2822(value)));
                    }
                }
            }
        } 

需要增加对普通日期格式的修改,修改后的代码如下所示

         public   DateTime Date
        {
              get  {
                  if ( this  .IsDisposed){
                      throw   new  ObjectDisposedException( this  .GetType().Name);
                }

                MIME_h h  =  this .Header.GetFirst( "  Date  "  );
                  if (h !=  null  ){
                      try  {
                          return   MIME_Utils.ParseRfc2822DateTime(((MIME_h_Unstructured)h).Value);
                    }
                      catch  {

                          //  尝试转换正常的日期 
                         DateTime dt;
                          string  dateString =  ((MIME_h_Unstructured)h).Value;
                          bool  success = DateTime.TryParse(dateString,  out   dt);
                          if   (success)
                        {
                              return   dt;
                        }
                          else  
                        {
                              throw   new  ParseException( "  Header field 'Date' parsing failed.  "  );
                        }
                    }                    
                }
                  else  {
                      return   DateTime.MinValue;
                }
            }

              set  {
                  if ( this  .IsDisposed){
                      throw   new  ObjectDisposedException( this  .GetType().Name);
                }
                
                  if (value ==  DateTime.MinValue){
                      this .Header.RemoveAll( "  Date  "  );
                }
                  else  {
                    MIME_h h  =  this .Header.GetFirst( "  Date  "  );
                      if (h ==  null  ){
                          this .Header.Add( new  MIME_h_Unstructured( "  Date  "  ,MIME_Utils.DateTimeToRfc2822(value)));
                    }
                      else  {
                          this .Header.ReplaceFirst( new  MIME_h_Unstructured( "  Date  "  ,MIME_Utils.DateTimeToRfc2822(value)));
                    }
                }
            }
        } 

2、由于意外的数据包格式,握手失败

错误信息 :[2013-05-04 10:13:54]    System.IO.IOException: 由于意外的数据包格式,握手失败。

   在 LumiSoft.Net.TCP.TCP_Client.Connect(String host, Int32 port, Boolean ssl)

错误原因 :由于POP3的配置端口不正确导致,一般的端口必须严格按照正常的来填写。

邮件SMTP 和POP3 常用配置说明:

邮箱

Smtp服务器

Smtp端口

POP3服务器

POP3端口

使用SSL

Gmail测试数据

smtp.gmail测试数据

pop.gmail测试数据

true

QQ测试数据

smtp.qq测试数据

pop.qq测试数据

true

163测试数据

smtp.163测试数据

pop.163测试数据

false

Sina测试数据

smtp.sina测试数据

pop.sina测试数据

false

其他

smtp.test测试数据

pop.test测试数据

false

 3、邮件标题乱码问题

错误信息 : 标题出现类似 =?utf-8?B?5rWL6K+V6YKu5Lu2?= 

错误原因 :这个是因为编码的问题,其中=?utf-8?B是表示该段字符为UTF-8的格式,后面的是base64格式的内容。除了utf-8,还可以出现gb2312或者ibm-euccn等格式。为了转换上面的编码问题,我写了一个转码函数,如下所示。

         private   string  DecodeString( string   input)
        {
              string  regex =  @"  =\?(?<encode>.*?)\?B\?(?<body>.*?)\?=  "  ;

            Regex re  =  new  Regex(regex, RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace |  RegexOptions.Multiline);
            MatchCollection mcs  =  re.Matches(input);
              foreach  (Match mc  in   mcs)
            {
                  string  encode = mc.Groups[ "  encode  "  ].Value;
                  if  (! string  .IsNullOrEmpty(encode))
                {
                      if  (encode.ToLower().Contains( "  euccn  " ) || encode.ToLower().Contains( "  euc-cn  " ) || 
                        encode.ToLower().Contains(  "  gbk  "  ))
                    {
                        encode  =  "  gb2312  "  ;
                    }
                      else   if  (encode.ToLower().Contains( "  utf8  "  ))
                    {
                        encode  =  "  utf-8  "  ;
                    }

                      string  body = mc.Groups[ "  body  "  ].Value;
                      byte [] bytes =  Convert.FromBase64String(body);
                      string  result =  Encoding.GetEncoding(encode).GetString(bytes);

                    input  =  input.Replace(mc.Value, result);
                }
            }
              return   input;
        } 

如可以通过代码吧标题进行转码解析

info.Title = DecodeString(mime_header.Subject);

转码后,标题和相关的内容都可以正常显示了。

除了上面的转码操作,还有一种更好的方法,能够使得邮件相关信息正常显示。

因为通过分析了解到,由于Lumisoft的Mail_Message.ParseFromByte函数默认只是以UTF8转换字节,一旦字节为GB2312格式,就会发生转换乱码问题,因此先经过Default编码转换,然后再以UTF8获取字节,即可正常转换邮件头部。

 byte [] utf8Bytes =  Encoding.UTF8.GetBytes(message.HeaderToString());
Mail_Message mime_header  = Mail_Message.ParseFromByte(utf8Bytes);

这样获取到的标题,以及邮件头部等信息,都是正常的了。

主要研究技术:代码生成工具、Visio二次开发、送水管理软件等共享软件开发
专注于 Winform开发框架 、WCF开发框架的研究及应用。
  转载请注明出处:
撰写人:伍华聪   http://HdhCmsTestiqidi测试数据  
    

 

 

标签:  开发辅助

作者: Leo_wl

    

出处: http://HdhCmsTestcnblogs测试数据/Leo_wl/

    

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权信息

查看更多关于基于Lumisoft.NET组件的POP3邮件接收和删除操作的详细内容...

  阅读:98次