深入Lumisoft.NET組件與.NET API實現郵件發送功能的對比分析_.Net教程

      編輯Tag賺U幣

      推薦:深入Lumisoft.NET實現郵件發送功能的方法詳解
      本篇文章對使用Lumisoft.NET實現郵件發送功能的方法機型了詳細的分析介紹。需要的朋友參考下

      我在另一篇文章《》有大致對這個Lumisoft.NET組件的使用進行了介紹,當然Lumisoft.NET組件除了提供郵件發送功能外,還提供了郵件接收等功能的處理(包括基于POP3協議和IMAP協議),而.NET則除了提供SMTP協議功能外,則沒有提供POP3協議處理的相關類庫,因此收取郵件這需要自己進行封裝(需要也可以參考codeproject.com上的相關文章)。

      1、.NET的郵件發送功能實現
      .NET本身封裝了一個SmtpClient類以及相關的郵件對象類,這樣利用這些類庫,也可以方便實現郵件的發送功能的了。

      如添加發送人地址,抄送地址,以及暗送地址(多個地址用逗號分開)代碼如下。

      復制代碼 代碼如下:www.wf0088.com

      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進行管理,他們的利用代碼如下所示:
      復制代碼 代碼如下:www.wf0088.com

      //附件
      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);


      發送郵件的其他部分代碼如下所示
      復制代碼 代碼如下:www.wf0088.com

      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發送郵件操作的完整代碼如下:
      復制代碼 代碼如下:www.wf0088.com

      /// <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對象即可。

      復制代碼 代碼如下:www.wf0088.com

      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操作如下所示。

      復制代碼 代碼如下:www.wf0088.com

      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格式的郵件操作如下所示。
      復制代碼 代碼如下:www.wf0088.com

      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格式的操作如下所示。
      復制代碼 代碼如下:www.wf0088.com

      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文件的相關操作如下所示。

      復制代碼 代碼如下:www.wf0088.com

      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文件操作如下所示。
      復制代碼 代碼如下:www.wf0088.com

      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組件開發碰到亂碼等問題的解決方法
      本篇文章介紹了,在Lumisoft.NET組件開發中碰到亂碼等一些問題的解決方法。需要的朋友參考下

      來源:模板無憂//所屬分類:.Net教程/更新時間:2013-05-08
      相關.Net教程