スキップしてメイン コンテンツに移動

MailKitの使い方! エンコーディング指定や添付ファイをメールで送信する方法[C#/VB Tips]

MailKitを使ってメールを送るサンプルコードです。(C#)

UTF8/iso-2022-jpのエンコーディング指定、GMail/YahooのSMTPサーバで送るなど、4つのサンプルコードでMailKitの使い方を紹介します。

MailKitって何?

2017年に.NET標準のSystem.Net.Mail.SmtpClientが廃止予定となり、Microsoftより今後はオープンソースライブラリである、MailKitに置き換えるとアナウンスがありました。

既にSmtpClientは非推奨になっており、今後は廃止されていきます。現在、SmtpClientを使用したソースコードには、Visual StudioからMailKitを使うよう警告が出るようになっています。

さっそく、MailKitを使ってメールを送信するサンプルコードを作っていきます。

UTF8でメールを送信

文字エンコーディングを、UTF8でメールを送信するサンプルコードです。
MailKitは、デフォルトの文字エンコーディングがUTF8なっている為、シンプルなコードでメールを送信する事ができます。

var host = "<smtp server name>";
var port = 25; // or 587

using (var smtp = new MailKit.Net.Smtp.SmtpClient()) {

    //SMTPサーバに接続する
    smtp.Connect(host, port, MailKit.Security.SecureSocketOptions.Auto);
    //認証が必要な場合は、以下のコメントを解除
    //smtp.Authenticate("<id>", "<password>");

    //送信するメールを作成する
    var mail = new MimeKit.MimeMessage();
    var builder = new MimeKit.BodyBuilder();
    mail.From.Add(new MimeKit.MailboxAddress("", "<from mail address>"));
    mail.To.Add(new MimeKit.MailboxAddress("", "<to mail address>"));
    mail.Subject = "メールの件名";
    builder.TextBody = "メールの本文です。\n\n以上";
    mail.Body = builder.ToMessageBody();

    //メールを送信する
    smtp.Send(mail);

    //SMTPサーバから切断する
    smtp.Disconnect(true);
}

文字エンコーディングを指定してメールを送信

次は、文字エンコーディングを指定して、メールを送るサンプルコードです。
iso-2022-jpでメールを送信します。

var host = "<smtp server name>";
var port = 25; // or 587
var enc = System.Text.Encoding.GetEncoding("iso-2022-jp");

using (var smtp = new MailKit.Net.Smtp.SmtpClient()) {
    smtp.Connect(host, port, MailKit.Security.SecureSocketOptions.Auto);
    smtp.Authenticate("<id>", "<password>");

    var mail = new MimeKit.MimeMessage();
    mail.From.Add(new MimeKit.MailboxAddress("", "<from mail address>"));
    mail.To.Add(new MimeKit.MailboxAddress("", "<to mail address>"));

    //(1)エンコーディング指定で、件名を設定 (Headers.Replaceで既存のヘッダを置換するのがミソ)
    mail.Headers.Replace(MimeKit.HeaderId.Subject, enc, "メールの件名");

    //(2)本文もエンコーディング指定で設定
    MimeKit.TextPart textPart = new MimeKit.TextPart("plain");
    textPart.SetText(enc, "メールの本文です。\n\n以上");
    // "iso-2022-jp"で送るので、"Content-Transfer-Encoding"に"7bit"を指定
    textPart.ContentTransferEncoding = MimeKit.ContentEncoding.SevenBit;
    mail.Body = textPart;

    smtp.Send(mail);
    smtp.Disconnect(true);
}

(1) の所で件名を、エンコーディング指定で設定しています。
注意すべきは、Headers.Addではなく、Headers.Replaceでヘッダを置換している所です。
MimeMessageクラスはインスタンスを作成する時点で、件名(Subjectヘッダ)が作成される為、置換して内容を書き換えます。
Headers.Addを使ってしまうと、2重に Subjectヘッダが作成されてしまいます。

(2) では、本文を作成しています。
TextPartクラスに本文の内容を、エンコーディング指定で設定します。
また、"iso-2022-jp"の JISコードで送る為、ContentTransferEncoding7bitを設定しています。

ネットを検索しても、MailKitで件名のエンコーディングを指定する方法が見つからず、正直苦労しました。
結局 MimeKitのソースを解析して、上のコードで送信出来ることが分かりました。

メールエイリアスを付けて送信する

メールエイリアスを付けて送信するサンプルコードです。
送信元、送信先のメールアドレスを設定する処理で、エイリアス(別名)とメールアドレスを設定します。

UTF8でエイリアスを設定する場合

mail.From.Add(new MimeKit.MailboxAddress("ネットショッピング通信", "xxxxxx@example.com"));
mail.To.Add(new MimeKit.MailboxAddress("山田 太郎", "xxxxxx@example.com"));

iso-2022-jpでエイリアスを設定する場合

var enc = System.Text.Encoding.GetEncoding("iso-2022-jp");
mail.From.Add(new MimeKit.MailboxAddress(enc, "ネットショッピング通信", "xxxxxx@example.com"));
mail.To.Add(new MimeKit.MailboxAddress(enc, "山田 太郎", "xxxxxx@example.com"));

Yahooメールで送信する

YahooのSMTPサーバを使ってメールを送信するサンプルコードです。
SMTPS(over SSL)でメールを暗号化します。
※ Yahoo Japanは STARTTLSには対応していない模様

var host = "smtp.mail.yahoo.co.jp";
var port = 465;

using (var smtp = new MailKit.Net.Smtp.SmtpClient()) {
    //(1)SMTPS(over SSL)で接続します。
    smtp.Connect(host, port, MailKit.Security.SecureSocketOptions.SslOnConnect);
    //(2)Yahooメールのアカウント(メールアドレスの@より前の部分)を指定して認証する
    smtp.Authenticate("<account>", "<password>");

    var mail = new MimeKit.MimeMessage();
    var builder = new MimeKit.BodyBuilder();

    mail.From.Add(new MimeKit.MailboxAddress("", "xxxxxxxx@yahoo.co.jp"));
    mail.To.Add(new MimeKit.MailboxAddress("", "<to mail address>"));
    mail.Subject = "メールの件名";
    builder.TextBody = "メールの本文です。\n\n以上";
    mail.Body = builder.ToMessageBody();

    smtp.Send(mail);
    smtp.Disconnect(true);
}

GMailで送信する

GMailのSMTPサーバを使ってメールを送信するサンプルコードです。
STARTTLSで送信します。

var host = "smtp.gmail.com";
var port = 587;

using (var smtp = new MailKit.Net.Smtp.SmtpClient()) {
    //(1)STARTTLSで接続する
    smtp.Connect(host, port, MailKit.Security.SecureSocketOptions.StartTls);
    //(2)GMailメールのアカウントを指定して認証する
    smtp.Authenticate("xxxxxxxx@gmail.com", "<password>");

    var mail = new MimeKit.MimeMessage();
    var builder = new MimeKit.BodyBuilder();

    mail.From.Add(new MimeKit.MailboxAddress("", "xxxxxxxx@gmail.com"));
    mail.To.Add(new MimeKit.MailboxAddress("", "<to mail address>"));
    mail.Subject = "メールの件名";
    builder.TextBody = "メールの本文です。\n\n以上";
    mail.Body = builder.ToMessageBody();

    smtp.Send(mail);
    smtp.Disconnect(true);
}

このサンプルでメールを送るには、Googleアカウントのセキュリティ設定を変更する必要があります。
※セキュリティが低くなるので、自己責任でお願いします。

設定 内容
2段階認証 オフ
安全性の低いアプリのアクセス オン

[関連リンク]
ログインとセキュリティ
安全性の低いアプリのアクセス

添付ファイルを送信する

Mailkitで添付ファイルを送信するサンプルコードです。
ファイルの添付には、MimeKit.MimePartクラスを使用します。

var filePath = "image.png";  //テンプファイルのパス

//(1)添付ファイルを設定
var attachment = new MimeKit.MimePart("image/png");
attachment.Content = new MimeKit.MimeContent(System.IO.File.OpenRead(filePath));
attachment.ContentDisposition = new MimeKit.ContentDisposition ();
attachment.ContentTransferEncoding = MimeKit.ContentEncoding.Base64;
attachment.FileName = System.IO.Path.GetFileName (filePath);

//メールの本文を設定
MimeKit.TextPart textPart = new MimeKit.TextPart ("plain");
textPart.Text = "メールの本文です。\n\n以上";

//(2)Multipartオブジェクトの作成
var multipart = new MimeKit.Multipart ("mixed");
multipart.Add (textPart);
multipart.Add (attachment);

//(3)Bodyに、添付ファイルとメール本文を格納したMultipartオブジェクトを設定
mail.Body = multipart;
smtp.Send (mail);  //メールを送信

(1) 添付ファイルの設定には、MimeKit.MimePartクラスを使用します。
コンストラクタには、送信するファイルのMimeTypeを指定し、それ以降のプロパティで送信するフィアルの情報を設定していきます。

(2) メールの本文と添付ファイルを合わせて送る為に、MimeKit.MultipartクラスにTextPartMimePartを設定します。

(3)メール本文と添付ファイルを設定したMimeKit.Multipartを、MimeKit.MimeMessageのBodyに指定して、メールを送信します。

ファイルの拡張子に合わせたMimeTypeを設定する

上で紹介したサンプルコードは、送信する添付ファイルのMimeTypeがimage/png固定で書かれおり、汎用性がありません。複数の拡張子を添付ファイルで送信する場合、MimeTypeをファイルの拡張子から動的に設定する必要があります。

MailKitには、ファイルの拡張子からMimeTypeを取得するMimeKit.MimeTypes.GetMimeTypeメソッドが用意されており、以下のコードを書くことで複数の拡張子に対応可能です。

var filePath = "image.jpg";  
  
//ファイルの拡張子からMIMEタイプを取得する
var mimeType = MimeKit.MimeTypes.GetMimeType(filePath);  //=> image/jpeg
var attachment = new  MimeKit.MimePart(mimeType);

MimeKit.MimeTypes.GetMimeTypeメソッドが対応している拡張子は、MailKitのソースコードに書かれてましたので、以下のリンクに対応している拡張子をまとめました。
MailKitのGetMimeTypeでMIMEタイプに変換できる拡張子一覧

参考情報

なぜ標準の SmtpClient ではなく、MailKitなの?

MailKit が、標準の SmtpClient 置き換わった経緯などは、2017/04/14に投稿された以下のリンクに詳しく書かれています。

また、.NET Framework 4.8のSmtpClientクラスのAPIドキュメントには、次のイメージのように、明確に廃止されたと記載があり、代わりにMailKitを使う事が推奨されています。

.NET Framework 4.8のSmtpClientクラスのAPIドキュメント

もし、過去にSmtpClientでメール送信する処理を組んでいて、新しい .NET Frameworkに移行する予定がある場合は、MailKitへの移行作業が発生することを、頭に入れておいてください。

ポート25, 587, 465の違い

メールを送信する時のSMTPのポート番号には、25, 587, 465のいずれかを使用します。ポート番号毎の用途について、以下にまとめました。

25番

特定のネットワークアドレス(社内など)からから認証なしで送信する用途に使われる。
メールの暗号化を行わない為、通常の用途では使用しない。

587番

一般的に、認証に成功した場合のみ送信を許可。
暗号化にはSTARTTLSを使用。

465番

認証に成功した場合のみ送信を許可。
暗号化にはSMTPS(over SSL)を使用。

MacのVisual StudioでMailKitを使用する

以下のリンクを参考ください。
MacのVisual StudioでMailKitを使用する方法のリンクを参考ください。

さいごに

MailKitを使ってメールを送る方法を紹介してきました。以前のSystem.Net.Mail.SmtpClientを使った人であれば、それほと使い方に大きな違いはないため、スッと理解できると思います。

スポンサーリンク
スポンサーリンク
スポンサーリンク

コメント

このブログの人気の投稿

axiosの使い方まとめ (GET/POST/例外処理)

axiosの使い方まとめ (GET/POST/例外処理)最近何かとよく使うJavaScriptでAJAX通信を行うaxiosについて、簡単に使い方をまとめました。GETリクエストをaxiosで送るまずはGETリクエストをaxiosで送る方法です。const res =await axios.get('/users') console.log(res.data)分割代入の記法を使うと、以下のようにも書けますconst{data}=await axios.get('/users') console.log(data)クエリパラメータ (URLパラメータ)を指定クエリパラメータを指定する方法は2つあります。1つ目は、axios.getに指定するURLに直接記述する方法です。axios.get('/user?id=123')2つめは、axios.getの第2引数に、オプション指定する方法です。axios.get('/user',{ params:{ id:123}})POSTリクエストをaxiosで送る次はPOSTリクエストをaxiosで送る方法です。JSON形式でPOSTするJSON形式でPOSTする場合は、axios.postの第2引数に、送信するデータをJavaScriptオブジェクトで指定します。const res =await axios.post('/user',{ id:123, name:'Yamada Tarou'})application/x-www-form-urlencoded形式でPOSTするapplication/x-www-form-urlencoded形式でPOSTする場合は、URLSearchParamsを使います。var params =newURLSearchParams() params.append('id',123) params.append('name','Yamada Tarou')const res =await axios.post('/user', params)axios でファイルをアップロードする画像などのファイルを、axiosでアッ…

[VB, C#] Windows 8, Window 10 で ImeModeが制御できない問題を解決する

[VB, C#] Windows 8, Window 10 で ImeModeが制御できない問題を解決するタイトルの通りですが、Windows 8 以降では Windows Form アプリケーションで、コントロールの ImeMode に Katakana や KatakanaHalf を設定しても、カタカナになってくれません。なぜ ImeMode が効かないのか?Windows 8 以降、IME Mode の切り替えは、ユーザー単位で切り替わるようになった為、アプリから IME Mode 制御が出来ないようになりました。
(IME をON にした場合、常に ひらがな モードになます)※ Windows 7までは、IME Modeの切り替えはアプリ単位で行われていた為、問題なくアプリから IME制御が行えました。対処方法Windows 8 以降、IMEの制御は、InputScope クラスの利用が推奨されています。
しかし、InputScope クラスは、WPF、Windows ストアアプリでしか使えない為、Windows Formアプリでは使用できません。
(Windows Form はもう使うな!という事でしょうか (涙) )結論としては、コントールパネルの設定で、IMEの制御をユーザ単位から アプリ単位に変更する事ができます。
これで、Windows Formアプリでも 従来通りIMEの制御を行う事が出来ます。おわりにこの方法だと、アプリをインストールする端末すべてに設定が必要となり、とっても面倒です。。。
しかし、今の所これしか方法がない状態です。
これからは Windows Formではなく、WPFや Windows ストアアプリで作れという事ですかね (^^;)