これまで広く使われてきたSmtpClientクラスは現在、使用が推奨されていない。そこでオープンソースライブラリのMailKitでメールを送信する方法を説明する。
.NET Framework 2.0以来、メール送信にはSystem.Net.Mail名前空間のSmtpClientクラスが使われてきた。ところが.NET Framework 4.5からは、サードパーティー製のMailKitライブラリが推奨されるようになっている。本稿では、MailKitを使ってメールを送信する方法を解説する。
特定のトピックをすぐに知りたいという方は以下のリンクを活用してほしい。
なお、本稿に掲載したサンプルコードをそのまま試すにはVisual Studio 2017以降が必要である。サンプルコードはコンソールアプリの一部であり、コードの冒頭に以下の宣言が必要となる。
using System;
using System.Text;
using static System.Console;
Imports System.Console
Imports System.Text
従来のSmtpClientクラス(System.Net.Mail名前空間)が「obsoleted(廃止)」扱いとなり、代わりにMailKitを使うように推奨されている。SmtpClientクラスの最新のドキュメントには、次の画像のような記載がある。
また、実際にも、本稿で解説するようにMailKitはとても使いやすい。MailKitが対応している.NET Framwork 4.5以降であれば、SmtpClientではなくMailKitを使うべきである。
MailKitは、次の3つのメールクライアントAPIを提供している。
MailKitを使えば、メール送信だけでなく、メール受信とIMAPサーバ上でのメール管理も行えるのである。本稿ではSMTPクライアントの使い方だけを紹介するので、詳しくはMailKitのドキュメントをご覧いただきたい。
MailKitは、プラットフォームも広くカバーしている。対応している主なプラットフォームには次のようなものがある。
MailKitはオープンソースのライブラリであり、そのソースコードはGitHubで公開されている。ライセンスはMITライセンスである。ライセンスを見ると、著作権はXamarin社(2016年からMicrosoftの子会社)になっている。
ソースコードをダウンロードして自分でビルドしても構わないが、通常はNuGetからプロジェクトに導入すればよい。
Visual StudioのNuGetパッケージ管理画面で「MailKit」を検索してインストールする(次の画像)。
MimeMessageクラス(MimeKit名前空間)のオブジェクトを作って宛先や本文などをセットし、SmtpClientクラス(MailKit.Net.Smtp名前空間)を使ってそれを送信する。
SMTPサーバのユーザー認証に使うユーザー名とパスワードを引数として受け取るメソッドにまとめると、次のコードのようになる。宛先やSMTPサーバ名などを「***」で伏せ字にしているが、実際には適切な文字列を設定していただきたい(以降も同様)。
static async void SendMailAsync(string userName, string password)
{
// MimeMessageを作り、宛先やタイトルなどを設定する
var message = new MimeKit.MimeMessage();
message.From.Add(new MimeKit.MailboxAddress("MailKit ユーザー", "***@***.com"));
message.To.Add(new MimeKit.MailboxAddress("MailKit 試験", "***@***.jp"));
// message.Cc.Add(……省略……);
// message.Bcc.Add(……省略……);
message.Subject = "MailKit でメールを送信するテスト";
// 本文を作る
var textPart = new MimeKit.TextPart(MimeKit.Text.TextFormat.Plain);
textPart.Text = @"MailKit を使ってメールを送ってみるテストです。";
// MimeMessageを完成させる
message.Body = textPart;
// SMTPサーバに接続してメールを送信する
using (var client = new MailKit.Net.Smtp.SmtpClient())
{
#if DEBUG
// 開発用のSMTPサーバが暗号化に対応していないときは、次の行を追加する
//client.ServerCertificateValidationCallback = (s, c, h, e) => true;
#endif
try
{
await client.ConnectAsync("smtp.***.com", 587);
WriteLine("接続完了");
// SMTPサーバがユーザー認証を必要としない場合は、次の2行は不要
await client.AuthenticateAsync(userName, password);
WriteLine("認証完了");
await client.SendAsync(message);
WriteLine("送信完了");
await client.DisconnectAsync(true);
WriteLine("切断");
}
catch (Exception ex)
{
WriteLine(ex.ToString());
}
}
}
Async Sub SendMailAsync(userName As String, password As String)
' MimeMessageを作り、宛先やタイトルなどを設定する
Dim message = New MimeKit.MimeMessage()
message.From.Add(New MimeKit.MailboxAddress("MailKit ユーザー", "***@***.com"))
message.To.Add(New MimeKit.MailboxAddress("MailKit 試験", "***@***.jp"))
' message.Cc.Add(……省略……)
' message.Bcc.Add(……省略……)
message.Subject = "MailKit でメールを送信するテスト"
' 本文を作る
Dim textPart = New MimeKit.TextPart(MimeKit.Text.TextFormat.Plain)
textPart.Text = "MailKit を使ってメールを送ってみるテストです。"
' MimeMessageを完成させる
message.Body = textPart
' SMTPサーバに接続してメールを送信する
Using client = New MailKit.Net.Smtp.SmtpClient()
#If DEBUG Then
' 開発用のSMTPサーバが暗号化に対応していないときは、次の行を追加する
' client.ServerCertificateValidationCallback = Function(s, c, h, e) True
#End If
Try
Await client.ConnectAsync("smtp.***.com", 587)
WriteLine("接続完了")
' SMTPサーバがユーザー認証を必要としない場合は、次の2行は不要
Await client.AuthenticateAsync(userName, password)
WriteLine("認証完了")
Await client.SendAsync(message)
WriteLine("送信完了")
Await client.DisconnectAsync(True)
WriteLine("切断")
Catch ex As Exception
WriteLine(ex.ToString())
End Try
End Using
End Sub
上のコードでは、宛先や本文などにわざと日本語を入れている。これで問題なくメールが届く。ただし、UTF-8でエンコードされる。
最近は、UTF-8のメールを表示できないメールクライアントアプリはほとんど見かけなくなった。それでも旧製品を使い続けているエンドユーザーに配慮して、JISコードでエンコーディングしておきたいこともあるだろう。
宛名などをJISコードで送るには、MailboxAddressクラス(MimeKit名前空間)のコンストラクタ引数にEncodingオブジェクト(System.Text名前空間)を与える(次のコード)。
// message.To.Add(new MimeKit.MailboxAddress("MailKit 試験", "***@***.jp"));
// ↓
var jis = Encoding.GetEncoding("iso-2022-jp");
message.To.Add(new MimeKit.MailboxAddress(jis, "MailKit 試験", "***@*.com"));
' message.To.Add(New MimeKit.MailboxAddress("MailKit 試験", "***@***.jp"))
' ↓
Dim jis = Encoding.GetEncoding("iso-2022-jp")
message.To.Add(New MimeKit.MailboxAddress(jis, "MailKit 試験", "***@***.com"))
本文をJISコードにするには、TextPartオブジェクト(MimeKit名前空間)に本文をセットするときに、TextプロパティではなくSetTextメソッドを使う。こちらは、Encodingオブジェクトを渡してもよいが、エンコーディング名でも構わない(次のコード)。
//textPart.Text = @"MailKit を使ってメールを送ってみるテストです。";
// ↓
textPart.SetText("iso-2022-jp",
@"MailKit を使ってメールを送ってみるテストです。");
'textPart.Text = "MailKit を使ってメールを送ってみるテストです。"
' ↓
textPart.SetText("iso-2022-jp",
"MailKit を使ってメールを送ってみるテストです。")
前述したテキストの本文だけを送信する場合には、MimeMessageオブジェクトのBodyプロパティにTextPartオブジェクトをセットした。
ファイルを添付する場合は、ファイルからMimePartオブジェクト(MimeKit名前空間)を作り、本文のTextPartオブジェクトと合わせてMultipartオブジェクト(MimeKit名前空間)に格納し、それをMimeMessageオブジェクトのBodyプロパティにセットする(次のコード)。
//message.Body = textPart;
// ↓
var path = @"C:\Windows\Web\Wallpaper\Theme2\img10.jpg"; // 添付したいファイル
var attachment = new MimeKit.MimePart("image", "jpeg")
{
Content = new MimeKit.MimeContent(System.IO.File.OpenRead(path)),
ContentDisposition = new MimeKit.ContentDisposition(),
ContentTransferEncoding = MimeKit.ContentEncoding.Base64,
FileName = System.IO.Path.GetFileName(path)
};
var multipart = new MimeKit.Multipart("mixed");
multipart.Add(textPart);
multipart.Add(attachment);
message.Body = multipart;
'message.Body = textPart
' ↓
Dim path = "C:\Windows\Web\Wallpaper\Theme2\img10.jpg" '添付したいファイル
Dim attachment = New MimeKit.MimePart("image", "jpeg") _
With {
.Content = New MimeKit.MimeContent(System.IO.File.OpenRead(path)),
.ContentDisposition = New MimeKit.ContentDisposition(),
.ContentTransferEncoding = MimeKit.ContentEncoding.Base64,
.FileName = System.IO.Path.GetFileName(path)
}
Dim multipart = New MimeKit.Multipart("mixed")
multipart.Add(textPart)
multipart.Add(attachment)
message.Body = multipart
メールを送信するには、従来のSmtpClientクラスに代わってサードパーティー製のMailKitライブラリが推奨されるようになった。MailKitは本稿で紹介したように簡単に使える上に、高機能である。
利用可能バージョン:.NET Framework 4.5以降
カテゴリ:オープンソースライブラリ 処理対象:Windowsフォーム
カテゴリ:オープンソースライブラリ 処理対象:WPF
カテゴリ:オープンソースライブラリ 処理対象:Xamarin.Forms
カテゴリ:クラスライブラリ 処理対象:電子メール
使用ライブラリ:MimeMessageクラス(MimeKit名前空間)
使用ライブラリ:SmtpClientクラス(MailKit.Net.Smtp名前空間)
関連TIPS:構文:インスタンス化と同時にプロパティを設定するには?[C#/VB]
関連TIPS:構文:クラス名を書かずに静的メソッドを呼び出すには?[C# 6.0]
関連TIPS:VB.NETでクラス名を省略してメソッドや定数を利用するには?
関連TIPS:数値を右詰めや0埋めで文字列化するには?[C#、VB]
Copyright© Digital Advantage Corp. All Rights Reserved.