找了一下,.NET有這個SmtpClient 類別可以來寄信,而且sample code也蠻詳細的,所以就來試一下了。
我是直接用需要帳號密碼登入才能用的gmail來寄,一開始的code是長這樣
private const string Username = "username"; //update your gmail acc/pw here
private const string Passowrd = "passowrd";
private string MailBody {
get
{
return string.IsNullOrEmpty(Request.QueryString["result"])
? string.Empty
: Request.QueryString["result"];
}
}
protected void Page_Load(object sender, EventArgs e)
{
if (MailBody == string.Empty) return;
using(var smtpServer = new SmtpClient("smtp.gmail.com", 587)
{
EnableSsl = true,
Timeout = 10000,
DeliveryMethod = SmtpDeliveryMethod.Network,
Credentials = new NetworkCredential(Username, Passowrd)
})
{
smtpServer.Send(new MailMessage("[email protected]", "[email protected]", "test", MailBody)
{
BodyEncoding = Encoding.UTF8,
DeliveryNotificationOptions = DeliveryNotificationOptions.OnFailure
});
}
}
其實這樣就可以寄了,但是拿不到成功或失敗的訊息,所以後來又加了SmtpClient.SendCompleted Event來去抓回應,這邊除了加上SendCompleted Event,寄信時原本是用.Send也要改成SendAsync,然後因為改成非同步模式,所以如果你在webpage上做的話,必須在 .aspx 的 <%@ Page %> 內加上 Async="true" ,不然會有錯誤訊息的。
原本以為這樣就可以拉到寄信的結果,結果我發現一直都是回應 Cancelled ,研究了很久,最後發現因為前面是使用 using 去叫 SmtpClient ,所以他事情做完就自動去 Dispose(),但是現在改用非同步模式去寄信,所以一Send SmtpClient 就被清掉,自然是不會有結果的(我猜他Dispose()時有可能自動做了SendAsyncCancel()還是因為物件不見就怎樣的關係),最後我改了寫法,長的像下面這樣。
private const string Username = "username"; //update your gmail acc/pw here
private const string Passowrd = "passowrd";
private string MailBody {
get
{
return string.IsNullOrEmpty(Request.QueryString["result"])
? string.Empty
: Request.QueryString["result"];
}
}
protected void Page_Load(object sender, EventArgs e)
{
if (MailBody == string.Empty) return;
var smtpServer = new SmtpClient("smtp.gmail.com", 587)
{
EnableSsl = true,
Timeout = 10000,
DeliveryMethod = SmtpDeliveryMethod.Network,
Credentials = new NetworkCredential(Username, Passowrd)
};
var message = new MailMessage("[email protected]", "[email protected]", "test", MailBody)
{
BodyEncoding = Encoding.UTF8,
DeliveryNotificationOptions = DeliveryNotificationOptions.OnFailure
};
smtpServer.SendCompleted += SendCompletedCallback;
try
{
smtpServer.SendAsync(message, "token");
}
catch (Exception ex)
{
Label1.Text = ex.Message;
}
}
private void SendCompletedCallback(object sender, AsyncCompletedEventArgs e)
{
// Get the unique identifier for this asynchronous operation.
var token = (string)e.UserState;
if (e.Cancelled)
{
Label1.Text = String.Format("[{0}] Send canceled.", token);
return;
}
Label1.Text = e.Error != null ? String.Format("[{0}] {1}", token, e.Error) : String.Format("Message [{0}] sent.", token);
}
使用SendAsync寄的時候,因為非同步的關係,所以會多要你傳一個token來辨識這是哪封信的結果,這在寄多封信的時候很有用,我這邊只寄一封信我就不理他了,詳情可以參閱SmtpClient.SendAsync 方法 (MailMessage, Object)。
基本上這樣就可以成功的用Gmail去幫你寄信了,這在自己做測試或監控,需要小量寄信的時候很方便,當然這段程式再延展起來也是可以拿來寄電子報、會員信之類的,就看你怎麼發揮了。

最後附上寄成功的信件內容,收工。
歐對了,我這個頁面的需求是會把QueryString "result"的內容寄出去,所以會多一小段東西,不然會更簡潔一點。
No comments:
Post a Comment