
Webブラウザでメールを送信する機能を追加したい。
C# でメールを送信するには MailKit を利用して送信することができます。MailKit はメールの送信や受信などメールに関する機能を提供する .NET 用のライブラリです。
サードパーティ製のライブラリの MailKit ですが、.NET 標準の StmpClient に置き換わるライブラリとして Microsoft が推奨しています。
この記事では、Mailkit を使ってメールを送信するサンプルコードを用いて分かりやすく紹介しています。ぜひ参考にしてみてください。

オススメの参考書
ASP.NET Core MVC(Model-View-Controller)の基本的な内容から、React.js や Vue.js との連携、Azure へのデプロイなどの周辺技術について記載されています。MVC フレームワークで開発をされる方に幅広くオススメしたい一冊です。新しい開発フレームワークにも対応している書籍です。
MailKit とは

MailKit(メールキット)とは、メールの送信や受信などメールに関する機能を提供する .NET 用のライブラリです。「SMTP クライアント」「POP3 クライアント」「IMAP4 クライアント」などのプロトコルをサポートしています。



標準ライブラリだったSystem.Net.Mail.StmpClientは廃止(非推奨)になっており、代わりに Microsoft の公式サイトでは MailKit を使うことを推奨しています。
2017年4月14日に Jonathan Allen 氏の記事に StmpClient から MailKit に置き換わった経緯などが記載されています。この記事やインターネットで調べた結果、StmpClient が非推奨の理由は以下の通りです。
- StmpClient は接続ライフサイクルが分かりにくい設計になっていること
 - StmpClient はメールの送信に必要な機能が不足していること
 - StmpClient はメンテナンスがされていないこと
 
\ MailKit の Githubサイトへ /
.NETでメール操作できる便利なライブラリ!!
MailKit は MimeKit に依存しており、MimeKit のクラスを利用します。
MimeKit は MIME(Multipurpose Internet Mail Extension)という規格に準拠しており、多くのメール関連の操作をサポートしています。
MIME について
メールは元々テキストベースのシステムで英語(ASCII コード)の仕様が前提でした。そのため、ASCII コード以外のデータ(日本語などマルチバイト文字や画像、音声)は扱うことができないデメリットがありました。
そのデメリットを解決したのがMIME。テキスト以外も扱えるようにデータを ASCII コードに変換する仕組みであり、メールでデータのやり取りを行う上でも欠かすことのできない重要なプロトコルとなっています。
MimeKit のインストール方法

それでは MailKit を ASP.NET のプロジェクトにインストールをしてみましょう。
インストールは NuGet から行えます。
ソリューションエクスプローラーからプロジェクト名で右クリックして、[NuGet パッケージの管理]をクリックします。

NuGet パッケージマネージャー画面が開くので、[参照]タブを選択して検索欄に「MailKit」と入力します。

検索結果の一覧にある Jeffrey Stedfast 氏が提供する「MailKit」を選択して、[インストール]ボタンをクリックします。

インストールが正常に完了すると、下図のようにアイコンに が付きます。

MailKitの使い方

ここからは MailKit の使い方について紹介します。紹介するサンプルコードは以下の環境で動作確認を行っています。
環境
- 統合開発環境:Visual Studio 2022
 - フレームワーク:.NET 7.0
 - MailKit のバージョン:4.3.0(公開日 2023/11/12)
 
インターフェイスを追加する
プロジェクトを起動して、ソリューションエクスプローラーを開きます。プロジェクトに「Services」フォルダを追加します。

そのフォルダに「IMailService.cs」という名前の新しいファイルを作成します。

IMailService.cs を開いて、次のコードを追加します。インターフェイスにSendAsyncメソッドを定義し、後述するメールを送信するクラスにこのインターフェイスを継承させます。
namespace SampleProject.Services
{
    public interface IMailService
    {
        Task SendAsync(string to, string from, string subject, string text);
    }
}メールを送信するクラスを追加する
Services フォルダに「MailService.cs」という名前の新しいファイルを作成します。

MailService.cs を開いて、MailServiceクラスにIMailServiceインターフェイスを継承します。
MailServiceクラスにSendAsyncメソッドを追加して、MailKit でメールを送信するロジックを記述します。
using System;
using System.Diagnostics;
namespace SampleProject.Services
{
    public class MailService : IMailService
    {
        private string smtpHost = "smtp.example.com";
        private int smtpPort = 123;
        private string userName = "xxxxxx@example.jp";
        private string password = "password";
        public async void SendAsync(string to, string from, string subject, string text)
        {
            // MimeMessageクラスのインスタンスを生成
            var message = new MimeKit.MimeMessage();
            // 送信元を追加  
            message.From.Add(new MimeKit.MailboxAddress("<送信元>", from));
            // 宛先を追加  
            message.To.Add(new MimeKit.MailboxAddress("<宛先>", to));
            // 件名を設定
            message.Subject = subject;
            // 本文を設定  
            var textPart = new MimeKit.TextPart(MimeKit.Text.TextFormat.Plain);
            textPart.Text = text;
            message.Body = textPart;
            using (var client = new MailKit.Net.Smtp.SmtpClient())
            {
                try
                {
                    // SMTPサーバに接続  
                    await client.ConnectAsync(smtpHost, smtpPort);
                    Debug.WriteLine("接続完了");
                    // SMTPサーバ認証  
                    await client.AuthenticateAsync(userName, password);
                    // 送信  
                    await client.SendAsync(message);
                    Debug.WriteLine("送信完了");
                    // 切断  
                    await client.DisconnectAsync(true);
                }
                catch (Exception ex)
                {
                    Debug.WriteLine($"Failed send:{ex}");
                }
            }
        }
    }
}上記のコードについて簡単に説明をします。
MimeMessageクラスのオブジェクトを作成する
var message = new MimeKit.MimeMessage();MimeMessageクラスのインスタンスを生成します。
このオブジェクトに、送信者(Fromプロパティ)、宛先(Toプロパティ、Ccプロパティ、Bccプロパティ)、件名(Subjectプロパティ)、本文(Bodyプロパティ)などのメールに関する情報を設定します。
StmpClientクラスでメールを送信する
MailKit のStmpClientクラスのインスタンスを生成します。
var client = new MailKit.Net.Smtp.SmtpClient()このオブジェクトに、SMTP サーバの URL、ポート番号、使用するアカウント名、パスワードなど必要な情報を設定して、SMTP サーバと通信を行います。
GmailのSMTPサーバーを利用して送信する
メールを送信するには、上記のSendAsyncメソッドに SMTP サーバーの情報を設定する必要があります。
Gmail の SMTP サーバーを使ってメールを送信するように、4つの変数(smtpHost、smtpPort、userName、password)を書き換えます。
smtpHost:smtp.gmail.comsmtpPort:587userName:Googleアカウントのメールアドレス(”@gmail.com”は除く)password:アプリ パスワード
SMTP サーバーで利用するpasswordは、Google アカウントのセキュリティ設定から2段階認証のアプリパスワードを設定する必要があります。※password は Google アカウントのパスワードではありません。
[Googleへのログイン]で[2段階認証プロセス]を選択します。

ページの下部までスクロールし、[アプリ パスワード]を選択します。

アプリパスワードが分かる名前を入力して[作成]ボタンをクリックします。
画面上に16桁のアプリ パスワードが表示されます。
Gmail の SMTP サーバーを使うようにしたサンプルコードが以下になります。
using System;
using System.Diagnostics;
namespace SampleProject.Services
{
    public class MailService : IMailService
    {
        private string smtpHost = "smtp.gmail.com";
        private int smtpPort = 587;
        private string userName = "xxxxxx";
        private string password = "1234567890123456";
        public async void SendAsync(string to, string from, string subject, string text)
        {
            // MimeMessageクラスのインスタンスを生成
            var message = new MimeKit.MimeMessage();
            // 宛先を追加  
            message.From.Add(new MimeKit.MailboxAddress("<宛名>", from));
            // 送り元を追加  
            message.To.Add(new MimeKit.MailboxAddress("<送信者名>", to));
            // 件名を設定
            message.Subject = subject;
            // 本文を設定  
            var textPart = new MimeKit.TextPart(MimeKit.Text.TextFormat.Plain);
            textPart.Text = text;
            message.Body = textPart;
            using (var client = new MailKit.Net.Smtp.SmtpClient())
            {
                try
                {
                    // SMTPサーバに接続  
                    await client.ConnectAsync(smtpHost, smtpPort);
                    Debug.WriteLine("接続完了");
                    // SMTPサーバ認証  
                    await client.AuthenticateAsync(userName, password);
                    // 送信  
                    await client.SendAsync(message);
                    Debug.WriteLine("送信完了");
                    // 切断  
                    await client.DisconnectAsync(true);
                }
                catch (Exception ex)
                {
                    Debug.WriteLine($"Failed send:{ex}");
                }
            }
        }
    }
}DI(依存性注入)を登録する
Program.cs を開いて、アプリケーションのコンテナーにMailServiceオブジェクトを登録します。
サービスの登録にはAddTransientメソッドを使って、サービスが要求される度に新しいインスタンスを生成して、使い終わったらオブジェクトを削除するようにします。
using SampleProject.Services;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllersWithViews();
builder.Services.AddTransient<IMailService, MailService>();
var app = builder.Build();
・
・
・追加したコードは5行目です。IMailServiceインターフェイスをコンテナに追加し、それをMailServiceクラスにマップしています。
メールデータを保持するモデルを追加する
Models フォルダに「MailViewModel.cs」という名前の新しいファイルを作成します。

このファイルにメールのデータ(宛先や送り元、件名、本文)を保持するプロパティを定義します。
namespace SampleProject.Models
{
    public class MailViewModel
    {
        public string SendTo { get; set; }
        
        public string SendFrom { get; set; }
        
        public string Subject { get; set; }
        public string Text { get; set; }
    }
}メールを送信するためのControllerを追加する
Controllers フォルダに「MailController.cs」という名前の新しいファイルを作成します。

MailController のコンストラクタの引数でMailServiceのオブジェクトを受け取り、クラス内の変数として定義している_mailServiceにセットします。
Indexメソッドのオーバーロードを用意して、MailViewModel に保持されたプロパティの値を使ってメールの送信を実行します。
using Microsoft.AspNetCore.Mvc;
using SampleProject.Models;
using SampleProject.Services;
namespace SampleProject.Controllers
{
    public class MailController : Controller
    {
        private readonly IMailService _mailService;
        public MailController(IMailService mailService)
        {
            _mailService = mailService;
        }
        public ActionResult Index()
        {
            return View(new MailViewModel());
        }
        [HttpPost]
        public async Task<IActionResult> Index(MailViewModel mailViewModel)
        {
            await _mailService.SendAsync(mailViewModel.SendTo, mailViewModel.SendFrom, mailViewModel.Subject, mailViewModel.Text);
            return View(mailViewModel);
        }
    }
}メールを送信するためのViewを追加する
Views フォルダに「Mail」という名前の新しいフォルダを作成します。

更に Mail フォルダに「Index」という名前の新しいファイルを作成します。

Index.cshtml を開いて、次のように記述します。
@model SampleProject.Models.MailViewModel
@{
    ViewData["Title"] = "Index";
}
<h2>メール送信</h2>
<hr />
<div class="row">
    <div class="col-md-4">
        <form asp-action="Index">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <div class="form-group">
                <label asp-for="SendTo" class="control-label"></label>
                <input asp-for="SendTo" class="form-control" />
                <span asp-validation-for="SendTo" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="SendFrom" class="control-label"></label>
                <input asp-for="SendFrom" class="form-control" />
                <span asp-validation-for="SendFrom" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Subject" class="control-label"></label>
                <input asp-for="Subject" class="form-control" />
                <span asp-validation-for="Subject" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Text" class="control-label"></label>
                <input asp-for="Text" class="form-control" />
                <span asp-validation-for="Text" class="text-danger"></span>
            </div>
            <div class="form-group">
                <input type="submit" value="Index" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>Webブラウザを起動する
それではデバッグを実行してみましょう。

メールの宛先、送り元、件名、本文を入力して[Index]ボタンをクリックすると、送信先のメールアドレスにメールが送信されます。
まとめ

この記事では、ASP.NET Core でメールを送信する方法について紹介しました。
MailKit ライブラリを NuGet からインストールして、メールを送信する処理を記述したMailServiceクラスを作成して、コントローラーのアクションメソッドで実行をしました。
メールを送信するには、.NET 標準の StmpClient からサードパーティー製の MailKit ライブラリが推奨されるようになっていますので、Web ブラウザからメールを送信したいという方は参考にしてみてください。



以上、最後まで読んで頂きありがとうございました。


					