寄發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的架構改變,這就要看個人的設計想法囉。
留言
張貼留言