注意:ここで紹介しているコードを実際に使用する場合は、必ずSMTPサーバー、送信者、宛先などの設定を適切に変更してください。
ここでは、.NET Framework 2.0からサポートされたSmtpClientクラスを使ってSMTPでメールを送信する基本的な方法を紹介します。なお、添付ファイル、HTMLメール、SMTP認証、SSL/TLSなどについては別のページで説明していますので、「インターネット編メニュー」をご覧ください。
.NET Framework 1.1以前でメールを送信する方法は、「SMTPでメールを送信する」をご覧ください。
まずは、最も簡単であろう例を示します。
'送信者 Dim senderMail As String = "sender@xxx.xxx" '宛先 Dim recipientMail As String = "recipient@xxx.xxx" '件名 Dim subject As String = "こんにちは" '本文 Dim body As String = "こんにちは。" + vbCrLf + vbCrLf + "それではまた。" 'SmtpClientオブジェクトを作成する Dim sc As New System.Net.Mail.SmtpClient() 'SMTPサーバーを指定する sc.Host = "localhost" 'ポート番号を指定する(既定値は25) sc.Port = 25 'メールを送信する sc.Send(senderMail, recipientMail, subject, body) '後始末(.NET Framework 4.0以降) sc.Dispose()
//送信者 string senderMail = "sender@xxx.xxx"; //宛先 string recipientMail = "recipient@xxx.xxx"; //件名 string subject = "こんにちは"; //本文 string body = "こんにちは。\r\n\r\nそれではまた。"; //SmtpClientオブジェクトを作成する System.Net.Mail.SmtpClient sc = new System.Net.Mail.SmtpClient(); //SMTPサーバーを指定する sc.Host = "localhost"; //ポート番号を指定する(既定値は25) sc.Port = 25; //SMTPサーバーに送信する設定にする(既定はNetwork) sc.DeliveryMethod = System.Net.Mail.SmtpDeliveryMethod.Network; //メールを送信する sc.Send(senderMail, recipientMail, subject, body); //後始末(.NET Framework 4.0以降) sc.Dispose();
上記のような方法で送信されたメールは、件名、本文ともに、文字コードUTF-8のBase64でエンコードされて送信されます(ただしアルファベットのみの場合は、件名はそのままで、本文はUS-ASCIIのQuoted-Printable)。具体的には、上記のコードでは、以下のように送信されます。
mime-version: 1.0 from: sender@xxx.xxx to: recipient@xxx.xxx date: 20 Jan 2007 22:05:18 +0900 subject: =?utf-8?B?44GT44KT44Gr44Gh44Gv?= content-type: text/plain; charset=utf-8 content-transfer-encoding: base64 44GT44KT44Gr44Gh44Gv44CCDQoNCuOBneOCjOOBp+OBr+OBvuOBn+OAgg== .
上記の方法ではSmtpClientクラスだけでメールを送信していましたが、今度はMailMessageオブジェクトを作成して、メールの送信に使用する方法を紹介します。
下の例では、FromとToに、メールアドレスのほかに、名前も指定しています。
'MailMessageの作成 Dim msg As New System.Net.Mail.MailMessage() '送信者(メールアドレスが"sender@xxx.xxx"、名前が"鈴木"の場合) msg.From = New System.Net.Mail.MailAddress("sender@xxx.xxx", "鈴木") '宛先(メールアドレスが"recipient@xxx.xxx"、名前が"加藤"の場合) msg.To.Add(New System.Net.Mail.MailAddress("recipient@xxx.xxx", "加藤")) '件名 msg.Subject = "こんにちは" '本文 msg.Body = "こんにちは。" + vbCrLf + vbCrLf + "それではまた。" Dim sc As New System.Net.Mail.SmtpClient() 'SMTPサーバーなどを設定する sc.Host = "localhost" sc.Port = 25 sc.DeliveryMethod = System.Net.Mail.SmtpDeliveryMethod.Network 'メッセージを送信する sc.Send(msg) '後始末 msg.Dispose() '後始末(.NET Framework 4.0以降) sc.Dispose()
//MailMessageの作成 System.Net.Mail.MailMessage msg = new System.Net.Mail.MailMessage(); //送信者(メールアドレスが"sender@xxx.xxx"、名前が"鈴木"の場合) msg.From = new System.Net.Mail.MailAddress("sender@xxx.xxx", "鈴木"); //宛先(メールアドレスが"recipient@xxx.xxx"、名前が"加藤"の場合) msg.To.Add(new System.Net.Mail.MailAddress("recipient@xxx.xxx", "加藤")); //件名 msg.Subject = "こんにちは"; //本文 msg.Body = "こんにちは。\r\n\r\nそれではまた。"; System.Net.Mail.SmtpClient sc = new System.Net.Mail.SmtpClient(); //SMTPサーバーなどを設定する sc.Host = "localhost"; sc.Port = 25; sc.DeliveryMethod = System.Net.Mail.SmtpDeliveryMethod.Network; //メッセージを送信する sc.Send(msg); //後始末 msg.Dispose(); //後始末(.NET Framework 4.0以降) sc.Dispose();
このように送信者、宛先に名前を指定したとき、これらはUTF-8 + Quoted-Printableでエンコードされます。
上記のメールは、具体的には次のように送信されます。
mime-version: 1.0 from: =?utf-8?Q?=E9=88=B4=E6=9C=A8?= <sender@xxx.xxx> to: =?utf-8?Q?=E5=8A=A0=E8=97=A4?= <recipient@xxx.xxx> date: 20 Jan 2007 22:23:05 +0900 subject: =?utf-8?B?44GT44KT44Gr44Gh44Gv?= content-type: text/plain; charset=utf-8 content-transfer-encoding: base64 44GT44KT44Gr44Gh44Gv44CCCgrjgZ3jgozjgafjga/jgb7jgZ/jgII= .
UTF-8以外の文字コードでメールを送信する場合は、文字コードを指定する必要があります。メールの件名と本文の文字コードは、MailMessageクラスのSubjectEncodingとBodyEncodingプロパティに指定します。送信者やあて先の名前の文字コードは、MailAddressのコンストラクタの3番目の引数に指定します。
以下に、JISコードを指定する例を示します。Encodingについて詳しくは、「文字コードを指定してテキストファイルを読み込む」をご覧ください。
'JISコード Dim enc As System.Text.Encoding = System.Text.Encoding.GetEncoding(50220) 'メッセージの作成 Dim msg As New System.Net.Mail.MailMessage() '件名と本文の文字コードを指定する msg.SubjectEncoding = enc msg.BodyEncoding = enc '送信者(メールアドレスが"sender@xxx.xxx"、名前が"鈴木"の場合) msg.From = New System.Net.Mail.MailAddress("sender@xxx.xxx", "鈴木", enc) '宛先(メールアドレスが"recipient@xxx.xxx"、名前が"加藤"の場合) msg.To.Add(New System.Net.Mail.MailAddress("recipient@xxx.xxx", "加藤", enc)) '件名 msg.Subject = "こんにちは" '本文 msg.Body = "こんにちは。" + vbCrLf + vbCrLf + "それではまた。" Dim sc As New System.Net.Mail.SmtpClient() 'SMTPサーバーなどを設定する sc.Host = "localhost" sc.Port = 25 sc.DeliveryMethod = System.Net.Mail.SmtpDeliveryMethod.Network 'メッセージを送信する sc.Send(msg) '後始末 msg.Dispose() '後始末(.NET Framework 4.0以降) sc.Dispose()
//JISコード System.Text.Encoding enc = System.Text.Encoding.GetEncoding(50220); //メッセージの作成 System.Net.Mail.MailMessage msg = new System.Net.Mail.MailMessage(); //件名と本文の文字コードを指定する msg.SubjectEncoding = enc; msg.BodyEncoding = enc; //送信者(メールアドレスが"sender@xxx.xxx"、名前が"鈴木"の場合) msg.From = new System.Net.Mail.MailAddress("sender@xxx.xxx", "鈴木", enc); //宛先(メールアドレスが"recipient@xxx.xxx"、名前が"加藤"の場合) msg.To.Add(new System.Net.Mail.MailAddress("recipient@xxx.xxx", "加藤", enc)); //件名 msg.Subject = "こんにちは"; //本文 msg.Body = "こんにちは。\r\n\r\nそれではまた。"; System.Net.Mail.SmtpClient sc = new System.Net.Mail.SmtpClient(); //SMTPサーバーなどを設定する sc.Host = "localhost"; sc.Port = 25; sc.DeliveryMethod = System.Net.Mail.SmtpDeliveryMethod.Network; //メッセージを送信する sc.Send(msg); //後始末 msg.Dispose(); //後始末(.NET Framework 4.0以降) sc.Dispose();
上記のコードを実行したときにSMTPサーバーに送信されるデータは、以下のようになります。
mime-version: 1.0 from: "=?iso-2022-jp?Q?=1B$BNkLZ=1B(B?=" <sender@xxx.xxx> to: "=?iso-2022-jp?Q?=1B$B2CF#=1B(B?=" <recipient@xxx.xxx> date: 20 Jan 2007 22:23:05 +0900 subject: =?iso-2022-jp?Q?=1B$B$3$s$K$A$O=1B(B?= content-type: text/plain; charset=iso-2022-jp content-transfer-encoding: quoted-printable =1B$B$3$s$K$A$O!#=1B(B=0A=0A=1B$B$=3D$l$G$O$^$?!#=1B(B .
これを見ていただければ分かるとおり、すべてQuoted-Printableでエンコードされます。
まずは、件名や送信者、あて先の名前をQuoted-Printableではなく、Base64でエンコードする方法を紹介します。これには、自分でエンコードを行い、MailMessageにはEncodingを指定しないで、そのまま送信するようにします。
以下に例を示します。まず、次のようなメソッドを作成します。
''' <summary> ''' メッセージヘッダのためのRFC2047形式の文字列に変換する(Base64) ''' </summary> ''' <param name="str">変換もとの文字列</param> ''' <param name="enc">エンコーディング</param> ''' <returns></returns> Private Function EncodeMailHeader(ByVal str As String, _ ByVal enc As System.Text.Encoding) As String 'Base64でエンコードする Dim ret As String = System.Convert.ToBase64String(enc.GetBytes(str)) 'RFC2047形式に ret = String.Format("=?{0}?B?{1}?=", enc.BodyName, ret) Return ret End Function
/// <summary> /// メッセージヘッダのためのRFC2047形式の文字列に変換する(Base64) /// </summary> /// <param name="str">変換もとの文字列</param> /// <param name="enc">エンコーディング</param> /// <returns></returns> private string EncodeMailHeader(string str, System.Text.Encoding enc) { //Base64でエンコードする string ret = System.Convert.ToBase64String(enc.GetBytes(str)); //RFC2047形式に ret = string.Format("=?{0}?B?{1}?=", enc.BodyName, ret); return ret; }
このメソッドを利用して、次のようにメールを送信します。
'JISコード Dim enc As System.Text.Encoding = System.Text.Encoding.GetEncoding(50220) 'メッセージの作成 Dim msg As New System.Net.Mail.MailMessage() '件名と本文の文字コードを指定する '送信者(メールアドレスが"sender@xxx.xxx"、名前が"鈴木"の場合) msg.From = New System.Net.Mail.MailAddress( _ "sender@xxx.xxx", EncodeMailHeader("""鈴木""", enc)) '宛先(メールアドレスが"recipient@xxx.xxx"、名前が"加藤"の場合) msg.To.Add(New System.Net.Mail.MailAddress( _ "recipient@xxx.xxx", EncodeMailHeader("""加藤""", enc))) '件名 msg.Subject = EncodeMailHeader("こんにちは", enc) '本文 msg.Body = "こんにちは。" + vbCrLf + vbCrLf + "それではまた。" Dim sc As New System.Net.Mail.SmtpClient() 'SMTPサーバーなどを設定する sc.Host = "localhost" sc.Port = 25 sc.DeliveryMethod = System.Net.Mail.SmtpDeliveryMethod.Network 'メッセージを送信する sc.Send(msg) '後始末 msg.Dispose() '後始末(.NET Framework 4.0以降) sc.Dispose()
//JISコード System.Text.Encoding enc = System.Text.Encoding.GetEncoding(50220); //メッセージの作成 System.Net.Mail.MailMessage msg = new System.Net.Mail.MailMessage(); //件名と本文の文字コードを指定する //送信者(メールアドレスが"sender@xxx.xxx"、名前が"鈴木"の場合) msg.From = new System.Net.Mail.MailAddress( "sender@xxx.xxx", EncodeMailHeader("\"鈴木\"", enc)); //宛先(メールアドレスが"recipient@xxx.xxx"、名前が"加藤"の場合) msg.To.Add(new System.Net.Mail.MailAddress( "recipient@xxx.xxx", EncodeMailHeader("\"加藤\"", enc))); //件名 msg.Subject = EncodeMailHeader("こんにちは", enc); //本文 msg.Body = "こんにちは。\r\n\r\nそれではまた。"; System.Net.Mail.SmtpClient sc = new System.Net.Mail.SmtpClient(); //SMTPサーバーなどを設定する sc.Host = "localhost"; sc.Port = 25; sc.DeliveryMethod = System.Net.Mail.SmtpDeliveryMethod.Network; //メッセージを送信する sc.Send(msg); //後始末 msg.Dispose(); //後始末(.NET Framework 4.0以降) sc.Dispose();
この方法で送信されるデータは、次のようになります。
mime-version: 1.0 from: =?iso-2022-jp?B?GyRCTmtMWhsoQg==?= <sender@xxx.xxx> to: =?iso-2022-jp?B?GyRCMkNGIxsoQg==?= <recipient@xxx.xxx> date: 20 Jan 2007 22:23:05 +0900 subject: =?iso-2022-jp?B?GyRCJDMkcyRLJEEkTxsoQg==?= content-type: text/plain; charset=utf-8 content-transfer-encoding: base64 44GT44KT44Gr44Gh44Gv44CCCgrjgZ3jgozjgafjga/jgb7jgZ/jgII= .
.NET Framework 4.5からは、MailMessage.BodyTransferEncodingプロパティを「SevenBit」にすることで、「content-transfer-encoding: 7bit」で送信することができます。
'JISコード Dim enc As System.Text.Encoding = System.Text.Encoding.GetEncoding(50220) 'MailMessageの作成 Dim msg As New System.Net.Mail.MailMessage("from@xxx.xxx", "to@xxx.xxx") msg.Subject = "題名" msg.SubjectEncoding = enc '本文と、本文の文字コードを設定する msg.Body = "こんにちは。" msg.BodyEncoding = enc '「content-transfer-encoding」を「7bit」にする msg.BodyTransferEncoding = System.Net.Mime.TransferEncoding.SevenBit Dim sc As New System.Net.Mail.SmtpClient() 'SMTPサーバーなどを設定する sc.Host = "localhost" sc.Port = 25 sc.DeliveryMethod = System.Net.Mail.SmtpDeliveryMethod.Network 'メッセージを送信する sc.Send(msg) '後始末 msg.Dispose() sc.Dispose()
//JISコード System.Text.Encoding enc = System.Text.Encoding.GetEncoding(50220); //MailMessageの作成 System.Net.Mail.MailMessage msg = new System.Net.Mail.MailMessage( "from@xxx.xxx", "to@xxx.xxx"); msg.Subject = "題名"; msg.SubjectEncoding = enc; //本文と、本文の文字コードを設定する msg.Body = "こんにちは。"; msg.BodyEncoding = enc; //「content-transfer-encoding」を「7bit」にする msg.BodyTransferEncoding = System.Net.Mime.TransferEncoding.SevenBit; System.Net.Mail.SmtpClient sc = new System.Net.Mail.SmtpClient(); //SMTPサーバーなどを設定する sc.Host = "localhost"; sc.Port = 25; sc.DeliveryMethod = System.Net.Mail.SmtpDeliveryMethod.Network; //メッセージを送信する sc.Send(msg); //後始末 msg.Dispose(); sc.Dispose();
これで送信されるデータは、以下のようになります。
MIME-Version: 1.0 From: from@xxx.xxx To: to@xxx.xxx Date: 25 Jun 2013 01:24:40 +0900 Subject: =?iso-2022-jp?Q?=1B=24BBjL=3E=1B=28B?= Content-Type: text/plain; charset=iso-2022-jp Content-Transfer-Encoding: 7bit こんにちは。 .
.NET Framework 4.0未満の場合は、おがわみつぎさんのこちらの記事で、「限りなく完全に近い」という方法が紹介されています。これはAlternateViewを使うという方法で、次のような感じです。
'JISコード Dim enc As System.Text.Encoding = System.Text.Encoding.GetEncoding(50220) 'MailMessageの作成 Dim msg As New System.Net.Mail.MailMessage("from@xxx.xxx", "to@xxx.xxx") msg.Subject = "題名" msg.SubjectEncoding = enc 'プレーンテキストのAlternateViewを作成 Dim htmlView As System.Net.Mail.AlternateView = _ System.Net.Mail.AlternateView.CreateAlternateViewFromString( _ "こんにちは。", enc, System.Net.Mime.MediaTypeNames.Text.Plain) 'TransferEncoding.SevenBitを指定 htmlView.TransferEncoding = System.Net.Mime.TransferEncoding.SevenBit 'AlternateViewを追加 msg.AlternateViews.Add(htmlView) Dim sc As New System.Net.Mail.SmtpClient() 'SMTPサーバーなどを設定する sc.Host = "localhost" sc.Port = 25 sc.DeliveryMethod = System.Net.Mail.SmtpDeliveryMethod.Network 'メッセージを送信する sc.Send(msg) '後始末 msg.Dispose() '後始末(.NET Framework 4.0以降) sc.Dispose()
//JISコード System.Text.Encoding enc = System.Text.Encoding.GetEncoding(50220); //MailMessageの作成 System.Net.Mail.MailMessage msg = new System.Net.Mail.MailMessage( "from@xxx.xxx", "to@xxx.xxx"); msg.Subject = "題名"; msg.SubjectEncoding = enc; //プレーンテキストのAlternateViewを作成 System.Net.Mail.AlternateView htmlView = System.Net.Mail.AlternateView.CreateAlternateViewFromString( "こんにちは。", enc, System.Net.Mime.MediaTypeNames.Text.Plain); //TransferEncoding.SevenBitを指定 htmlView.TransferEncoding = System.Net.Mime.TransferEncoding.SevenBit; //AlternateViewを追加 msg.AlternateViews.Add(htmlView); System.Net.Mail.SmtpClient sc = new System.Net.Mail.SmtpClient(); //SMTPサーバーなどを設定する sc.Host = "localhost"; sc.Port = 25; sc.DeliveryMethod = System.Net.Mail.SmtpDeliveryMethod.Network; //メッセージを送信する sc.Send(msg); //後始末 msg.Dispose(); //後始末(.NET Framework 4.0以降) sc.Dispose();
.NET Framework 2.0の場合、これで送信されるデータは、次のようなものです。
mime-version: 1.0 from: from@xxx.xxx to: to@xxx.xxx date: 23 Jan 2007 01:21:43 +0900 subject: =?iso-2022-jp?Q?=1B$BBjL>=1B(B?= content-type: text/plain; charset=iso-2022-jp content-transfer-encoding: sevenbit こんにちは。 .
"Content-Transfer-Encoding"が"7bit"ではなく"sevenbit"になっていますが、この問題はすでに修正されています。詳しくは、「FIX: The value of the TransferEncoding property may be incorrect when you run a Visual Studio 2005 program that uses the System.Net.Mime or System.Net.Mail namespaces」をご覧ください。(コメントにてご報告いただきました。)
Sendメソッドは同期的にメールを送信するため、Sendメソッドを呼び出すと、その処理がすべて終了するまでブロックされます。送信の処理が思ったよりずっと長くかかってしまうと困る場合は、SmtpClient.Timeoutプロパティでタイムアウトする時間を指定することができます。時間はミリ秒で指定し、デフォルトは100000ミリ秒(100秒)です。
Dim sc As New System.Net.Mail.SmtpClient() 'SMTPサーバーなどを設定する sc.Host = "localhost" sc.Port = 25 sc.DeliveryMethod = System.Net.Mail.SmtpDeliveryMethod.Network 'タイムアウトする時間を1分に設定する sc.Timeout = 60000 'メールを送信する sc.Send("a@xxx.xxx", "b@xxx.xxx", "題名", "本文") '後始末(.NET Framework 4.0以降) sc.Dispose()
System.Net.Mail.SmtpClient sc = new System.Net.Mail.SmtpClient(); //SMTPサーバーなどを設定する sc.Host = "localhost"; sc.Port = 25; sc.DeliveryMethod = System.Net.Mail.SmtpDeliveryMethod.Network; //タイムアウトする時間を1分に設定する sc.Timeout = 60000; //メールを送信する sc.Send("a@xxx.xxx", "b@xxx.xxx", "題名", "本文"); //後始末(.NET Framework 4.0以降) sc.Dispose();
SmtpClient.SendAsyncメソッドにより、非同期的にメールを送信することもできます。非同期的な送信では、送信に時間のかかるような場合でも、アプリケーションがフリーズしたように固まることがなくなります。
SendAsyncメソッドで非同期送信を行うと、SendAsyncCancelメソッドでその処理を途中でキャンセルできます。送信が完了すれば、SendCompletedイベントが発生します。
以下に非同期的にメールを送信する例を示します。ここでは、Button1をクリックすることによりメールの送信を開始し、送信が終了すると完了のメッセージが表示されます。Button2をクリックすることにより、送信を途中でキャンセルできます。
'SmtpClientオブジェクト Dim sc As System.Net.Mail.SmtpClient = Nothing 'Button1のClickイベントハンドラ Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) _ Handles Button1.Click Button1.Enabled = False Button2.Enabled = True 'MailMessageの作成 Dim msg As New System.Net.Mail.MailMessage( _ "sender@xxx.xxx", "recipient@xxx.xxx", "題名", "本文") 'SmtpClientの作成 If sc Is Nothing Then sc = New System.Net.Mail.SmtpClient() 'イベントハンドラの追加 AddHandler sc.SendCompleted, AddressOf sc_SendCompleted End If 'SMTPサーバーなどを設定する sc.Host = "localhost" sc.Port = 25 sc.DeliveryMethod = System.Net.Mail.SmtpDeliveryMethod.Network 'メールを送信する 'MailMessageをSendCompletedイベントハンドラで取得できるようにする sc.SendAsync(msg, msg) End Sub 'Button2のClickイベントハンドラ Private Sub Button2_Click(ByVal sender As Object, ByVal e As EventArgs) _ Handles Button2.Click 'メールの送信をキャンセルする If Not (sc Is Nothing) Then sc.SendAsyncCancel() End If End Sub 'メール送信が完了したとき Private Sub sc_SendCompleted(ByVal sender As Object, _ ByVal e As System.ComponentModel.AsyncCompletedEventArgs) 'SendAsyncで指定されたMailMessageを取得する Dim msg As System.Net.Mail.MailMessage = _ CType(e.UserState, System.Net.Mail.MailMessage) If e.Cancelled Then Console.WriteLine("[{0}]の送信はキャンセルされました。", msg.Subject) Else If Not (e.Error Is Nothing) Then Console.WriteLine("[{0}]の送信でエラーが発生しました。", msg.Subject) Console.WriteLine(e.Error.Message) Else Console.WriteLine("[{0}]の送信が完了しました。", msg.Subject) End If End If '後始末 msg.Dispose() Button1.Enabled = True Button2.Enabled = False End Sub
//SmtpClientオブジェクト System.Net.Mail.SmtpClient sc = null; //Button1のClickイベントハンドラ private void Button1_Click(object sender, EventArgs e) { Button1.Enabled = false; Button2.Enabled = true; //MailMessageの作成 System.Net.Mail.MailMessage msg = new System.Net.Mail.MailMessage( "sender@xxx.xxx", "recipient@xxx.xxx", "題名", "本文"); //SmtpClientの作成 if (sc == null) { sc = new System.Net.Mail.SmtpClient(); //イベントハンドラの追加 sc.SendCompleted += new System.Net.Mail.SendCompletedEventHandler(sc_SendCompleted); } //SMTPサーバーなどを設定する sc.Host = "localhost"; sc.Port = 25; sc.DeliveryMethod = System.Net.Mail.SmtpDeliveryMethod.Network; //メールを送信する //MailMessageをSendCompletedイベントハンドラで取得できるようにする sc.SendAsync(msg, msg); } //Button2のClickイベントハンドラ private void Button2_Click(object sender, EventArgs e) { //メールの送信をキャンセルする if (sc != null) sc.SendAsyncCancel(); } //メール送信が完了したとき private void sc_SendCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e) { //SendAsyncで指定されたMailMessageを取得する System.Net.Mail.MailMessage msg = (System.Net.Mail.MailMessage)e.UserState; if (e.Cancelled) { Console.WriteLine("[{0}]の送信はキャンセルされました。", msg.Subject); } else if (e.Error != null) { Console.WriteLine("[{0}]の送信でエラーが発生しました。", msg.Subject); Console.WriteLine(e.Error.Message); } else { Console.WriteLine("[{0}]の送信が完了しました。", msg.Subject); } //後始末 msg.Dispose(); Button1.Enabled = true; Button2.Enabled = false; }
なお、非同期送信ではTimeoutプロパティは無視されます。タイムアウトする時間は、自分で実装する必要があります。
アプリケーションやコンピュータ構成ファイルに、SMTPサーバー、ポート番号、認証に使用するユーザー名とパスワード、さらに"From"のデフォルトを記述しておくことができます。このようにすると、プログラムでこれらを指定する必要がなくなります。なお、アプリケーション構成ファイルに関しては、こちらをご覧ください。
具体的には、たとえば次のような記述をアプリケーション構成ファイルに追加します。
<configuration> <system.net> <mailSettings> <smtp deliveryMethod="Network" from="from@xxx.xxx"> <network host="localhost" port="25" userName="user" password="pass" /> </smtp> </mailSettings> </system.net> </configuration>
こうすると、以下のように、From、SMTPサーバー、ユーザー名、パスワードを指定しないでメールを送信することができるようになります。
'MailMessageの作成 Dim msg As New System.Net.Mail.MailMessage() '宛先 msg.To.Add("recipient@xxx.xxx") '件名 msg.Subject = "こんにちは" '本文 msg.Body = "こんにちは。それではまた。" Dim sc As New System.Net.Mail.SmtpClient() 'メッセージを送信する sc.Send(msg) '後始末 msg.Dispose() '後始末(.NET Framework 4.0以降) sc.Dispose()
//MailMessageの作成 System.Net.Mail.MailMessage msg = new System.Net.Mail.MailMessage(); //宛先 msg.To.Add("recipient@xxx.xxx"); //件名 msg.Subject = "こんにちは"; //本文 msg.Body = "こんにちは。\r\n\r\nそれではまた。"; System.Net.Mail.SmtpClient sc = new System.Net.Mail.SmtpClient(); //メッセージを送信する sc.Send(msg); //後始末 msg.Dispose(); //後始末(.NET Framework 4.0以降) sc.Dispose();
アプリケーション構成ファイルで指定した値はあくまでデフォルトの値なので、コードで指定した値が優先されます。
また、上記ではdefaultCredentialsを指定しませんでしたが、「defaultCredentials="true"」のように指定することもできます。ただしこの場合、userNameとpasswordは無視されます。
補足:.NET Framework 4.0からは、clientDomain、enableSsl、targetNameの設定もできるようになりました。
アプリケーション構成ファイルのmailSettingsに記述されている設定は、次のようにして取得することができます。なお、参照に「System.Configuration.dll」を加える必要があります。
'アプリケーション構成ファイルのmailSettingsの設定を取得 Dim smtpSec As System.Net.Configuration.SmtpSection = _ CType(System.Configuration.ConfigurationManager.GetSection( _ "system.net/mailSettings/smtp"), _ System.Net.Configuration.SmtpSection) Console.WriteLine("From:{0}", smtpSec.From) Console.WriteLine("Host:{0}", smtpSec.Network.Host) Console.WriteLine("Port:{0}", smtpSec.Network.Port) Console.WriteLine("UserName:{0}", smtpSec.Network.UserName) Console.WriteLine("Password:{0}", smtpSec.Network.Password)
//アプリケーション構成ファイルのmailSettingsの設定を取得
System.Net.Configuration.SmtpSection smtpSec =
(System.Net.Configuration.SmtpSection)
System.Configuration.ConfigurationManager.GetSection(
"system.net/mailSettings/smtp");
Console.WriteLine("From:{0}", smtpSec.From);
Console.WriteLine("Host:{0}", smtpSec.Network.Host);
Console.WriteLine("Port:{0}", smtpSec.Network.Port);
Console.WriteLine("UserName:{0}", smtpSec.Network.UserName);
Console.WriteLine("Password:{0}", smtpSec.Network.Password);
ASP.NETでは、次のようにします。「System.Configuration.dll」と「System.Web.dll」の参照が必要です。
'Web構成ファイルのmailSettingsの設定を取得 Dim config As System.Configuration.Configuration = _ System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration( _ HttpContext.Current.Request.ApplicationPath) Dim mailSet As System.Net.Configuration.MailSettingsSectionGroup = _ CType(config.GetSectionGroup("system.net/mailSettings"), _ System.Net.Configuration.MailSettingsSectionGroup) Console.WriteLine("From:{0}", mailSet.Smtp.From) Console.WriteLine("Host:{0}", mailSet.Smtp.Network.Host) Console.WriteLine("Port:{0}", mailSet.Smtp.Network.Port) Console.WriteLine("UserName:{0}", mailSet.Smtp.Network.UserName) Console.WriteLine("Password:{0}", mailSet.Smtp.Network.Password)
//Web構成ファイルのmailSettingsの設定を取得
System.Configuration.Configuration config =
System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration(
HttpContext.Current.Request.ApplicationPath);
System.Net.Configuration.MailSettingsSectionGroup mailSet =
(System.Net.Configuration.MailSettingsSectionGroup)
config.GetSectionGroup("system.net/mailSettings");
Console.WriteLine("From:{0}", mailSet.Smtp.From);
Console.WriteLine("Host:{0}", mailSet.Smtp.Network.Host);
Console.WriteLine("Port:{0}", mailSet.Smtp.Network.Port);
Console.WriteLine("UserName:{0}", mailSet.Smtp.Network.UserName);
Console.WriteLine("Password:{0}", mailSet.Smtp.Network.Password);
または、次のような方法もあります。
'Web構成ファイルのmailSettingsの設定を取得 Dim smtpSec As System.Net.Configuration.SmtpSection = _ CType( _ System.Web.Configuration.WebConfigurationManager.GetWebApplicationSection( _ "system.net/mailSettings/smtp"), System.Net.Configuration.SmtpSection) Console.WriteLine("From:{0}", smtpSec.From) Console.WriteLine("Host:{0}", smtpSec.Network.Host) Console.WriteLine("Port:{0}", smtpSec.Network.Port) Console.WriteLine("UserName:{0}", smtpSec.Network.UserName) Console.WriteLine("Password:{0}", smtpSec.Network.Password)
//Web構成ファイルのmailSettingsの設定を取得
System.Net.Configuration.SmtpSection smtpSec =
(System.Net.Configuration.SmtpSection)
System.Web.Configuration.WebConfigurationManager.GetWebApplicationSection(
"system.net/mailSettings/smtp");
Console.WriteLine("From:{0}", smtpSec.From);
Console.WriteLine("Host:{0}", smtpSec.Network.Host);
Console.WriteLine("Port:{0}", smtpSec.Network.Port);
Console.WriteLine("UserName:{0}", smtpSec.Network.UserName);
Console.WriteLine("Password:{0}", smtpSec.Network.Password);
上で紹介した以外に、次のような問題もあるようです。
アンチウィルス系のアプリケーションを使用しており、送信されるメールのチェックを行っている場合などでは、SmtpClient.Sendメソッドでメールを送信してもすぐには送信されない場合があるようです。この解決法は、「Delayed send with smtpclient in .net 2.0」で紹介されています。これによると、SmtpClientのServicePoint.MaxIdleTimeを1にすればよいとのことです(その後の投稿には、1000の方がよいともあります)。
Dim sc As New System.Net.Mail.SmtpClient() 'SMTPサーバーを指定する sc.Host = "localhost" '↓を追加 sc.ServicePoint.MaxIdleTime = 1 'メールを送信する sc.Send("a@xxx.xxx", "b@xxx.xxx", "題名", "本文")
System.Net.Mail.SmtpClient sc = new System.Net.Mail.SmtpClient(); //SMTPサーバーを指定する sc.Host = "localhost"; //↓を追加 sc.ServicePoint.MaxIdleTime = 1; //メールを送信する sc.Send("a@xxx.xxx", "b@xxx.xxx", "題名", "本文");
これでもダメならば、アンチウィルスソフトが送信されるメールのチェックをしないように設定してください。
他のメールクライアントでは正常に送信することができるメールアドレスに送信しようとしても、FormatException例外がスローされて送信できないケースがあるようです。この問題については、「SmtpClientでメールを送信しようとするとFormatExceptionが発生する問題の解決法」で詳しく説明します。