寄發EMail是許多系統常用必備的功能,.Net也有提供EMail相關操作的Class與Sample Code,所以要實作寄送EMail的功能是非常簡單的,要如何提高重覆使用性與彈性才是重點。
MailUtility因為限量覺得單純只提供Mail相關功能,所以就把它實作成static class,一些從App.config讀取的資訊限制不能改變,所以宣告成static readonly與const的類型,在靜態建構子裡就從App.config裡取出相關資訊,當然,如果再取出的途中發生錯誤就會直接丟出錯誤。這裡提供兩種SendMail的多載,傳入收件者EMail位址陣, 信件主旨與內容,其實呼叫的都是同一個,只是差別在是否要傳送檔案,如果傳送成功就回傳true,反之傳送發生錯誤會回傳false。
App.config : 設置EMail基本資訊(STMP Server位置, 寄件者...)
App.config可以自訂設置Mail的基本資訊,在這特別的是sectionGroup,這和之前提到的自訂App.config那篇有點不一樣,這裡就來簡單的說一下,使用sectionGroup,顧名思義,就是section的group,在上面可以看到Custom Region裡有Mail Section,因為Custom Region是sectionGroup,所以可以在裡面放其他的section。
Program.cs : 主程式
這MailUtility算是個小試身手的小程式,未考慮到其他情況,例如寄件, 讀取...等,這些其他功能也許會使這個MailUtility的架構改變,這就要看個人的設計想法囉。
針對重覆使用性,限量決定將Mail功能抽出來成為一個Utility,使用時只要簡單的呼叫MailUtility的方法就可以直接使用;針對設定的彈性上,限量決定與前先日子練習的自訂App.config結合,讓一些EMail相關的基本設定可以在App.config裡進行更改,下面就讓我們來看看細節如何實作:
MailConfigSection.cs : 定義App.config裡Mail Section裡對應的屬性
MailConfigSection是為了讓程式可以識別我們在App.config裡所定義的自訂section(在 App.config自訂section程式碼架構 這篇文章中有簡單的教大家如何使用),這裡限量定義了幾個Mail可能用到的一些屬性,像ServerAddress(SMTP Server位址,例如GMail, HotMail...等), Sender(寄件者EMail位址帳號), Password(寄件者EMail密碼), SenderName(寄件者名稱)。
MailUtility.cs : 提供EMail相關功能
MailConfigSection.cs : 定義App.config裡Mail Section裡對應的屬性
using System; using System.Configuration; namespace SendMailTest { public class MailConfigSection : ConfigurationSection { [ConfigurationProperty( "ServerInfo" )] public MailElement MailSettings { get { return (MailElement)this["ServerInfo"]; } } } public class MailElement : GenericElement { public override Object ElementKey { get { return this.Sender; } } [ConfigurationProperty( "ServerAddress" )] public String ServerAddress { get { return this["ServerAddress"].ToString(); } } [ConfigurationProperty( "Sender" )] public String Sender { get { return this["Sender"].ToString(); } } [ConfigurationProperty( "Password" )] public String Password { get { return this["Password"].ToString(); } } [ConfigurationProperty( "SenderName" )] public String SenderName { get { return this["SenderName"].ToString(); } } } }
MailConfigSection是為了讓程式可以識別我們在App.config裡所定義的自訂section(在 App.config自訂section程式碼架構 這篇文章中有簡單的教大家如何使用),這裡限量定義了幾個Mail可能用到的一些屬性,像ServerAddress(SMTP Server位址,例如GMail, HotMail...等), Sender(寄件者EMail位址帳號), Password(寄件者EMail密碼), SenderName(寄件者名稱)。
MailUtility.cs : 提供EMail相關功能
using System; using System.Linq; using System.Net; using System.Net.Mail; using System.Configuration; namespace SendMailTest { public static class MailUtility { #region Mail基本資訊 private static readonly String SMTP_ADDRESS; private static readonly String PASSWORD; private static readonly String SENDER_ADDRESS; private static readonly String SENDER_NAME; private const Int32 PORT = 1104; private const Boolean ENABLE_SSL = true; #endregion static MailUtility() { try { var section = ConfigurationManager.GetSection( "Custom/Mail" ) as MailConfigSection; var mailSetting = section.MailSettings; SMTP_ADDRESS = mailSetting.ServerAddress; SENDER_ADDRESS = mailSetting.Sender; PASSWORD = mailSetting.Password; SENDER_NAME = mailSetting.SenderName; } catch(Exception ex) { throw ex; } } public static Boolean SendMail( String[] receivers, String subject, String content ) { return SendMail( receivers, subject, content, String.Empty ); } public static Boolean SendMail( String[] receivers, String subject, String content, String file ) { Boolean status = true; try { using ( MailMessage mail = new MailMessage() ) { mail.From = new MailAddress( SENDER_ADDRESS, SENDER_NAME ); receivers.ToList().ForEach( e => mail.To.Add( e ) ); mail.Subject = subject; if ( file != String.Empty ) { Attachment attachFile = new Attachment( file ); mail.Attachments.Add( attachFile ); } mail.Body = content; mail.IsBodyHtml = true; using ( SmtpClient smtp = new SmtpClient( SMTP_ADDRESS, PORT ) ) { smtp.Credentials = new NetworkCredential( SENDER_ADDRESS, PASSWORD ); smtp.EnableSsl = ENABLE_SSL; smtp.Send( mail ); } } } catch ( Exception ex ) { status = false; } return status; } } }
MailUtility因為限量覺得單純只提供Mail相關功能,所以就把它實作成static class,一些從App.config讀取的資訊限制不能改變,所以宣告成static readonly與const的類型,在靜態建構子裡就從App.config裡取出相關資訊,當然,如果再取出的途中發生錯誤就會直接丟出錯誤。這裡提供兩種SendMail的多載,傳入收件者EMail位址陣, 信件主旨與內容,其實呼叫的都是同一個,只是差別在是否要傳送檔案,如果傳送成功就回傳true,反之傳送發生錯誤會回傳false。
App.config : 設置EMail基本資訊(STMP Server位置, 寄件者...)
<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <sectionGroup name="Custom"> <section name="Mail" type="SendMailTest.MailConfigSection, SendMailTest" /> </sectionGroup> </configSections> <!--設置SMTP Server位置與發送者的帳密--> <!--ServerAddress為Mail Server 位址,Sender為發送者帳號,Password為發送者密碼--> <Custom> <Mail> <ServerInfo ServerAddress="smtp.gmail.com" Sender="XXX@gmail.com" Password="xxxxxx" SenderName="限量"></ServerInfo> </Mail> </Custom> <!--設置SMTP Server位置與發送者的帳密--> <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" /> </startup> </configuration>
App.config可以自訂設置Mail的基本資訊,在這特別的是sectionGroup,這和之前提到的自訂App.config那篇有點不一樣,這裡就來簡單的說一下,使用sectionGroup,顧名思義,就是section的group,在上面可以看到Custom Region裡有Mail Section,因為Custom Region是sectionGroup,所以可以在裡面放其他的section。
Program.cs : 主程式
using System; namespace SendMailTest { class Program { static void Main( string[] args ) { var msg = MailUtility.SendMail( new[] { "XXXX@hotmail.com", "XXXX@gmail.com" }, "測試Mail", "這是封測試郵件" ) ? "發送成功" : "發送失敗"; Console.WriteLine(msg); Console.Read(); } } }
這MailUtility算是個小試身手的小程式,未考慮到其他情況,例如寄件, 讀取...等,這些其他功能也許會使這個MailUtility的架構改變,這就要看個人的設計想法囉。
留言
張貼留言