👏

【ASP.NET MVC】DockerとMailpitを使ってメール送信テスト

2024/05/22に公開

環境:
Windows 11 Home
Visutal studio 2022
WSL2(Ubuntu)

Visual Studioで新しいプロジェクトを作成:

Package Manager Consoleを使用して下記をインストール:

Install-Package MimeKit
Install-Package MailKit

メール送信の準備:
Program.cs

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddControllersWithViews();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Contacts}/{action=Create}/{id?}");

app.Run();

Models/Contacts.cs

using System.ComponentModel.DataAnnotations;

public class Contact
{
    public int Id { get; set; }

    [Required(ErrorMessage = "お名前を入力してください。")]
    public string Name { get; set; }

    [Required(ErrorMessage = "メールアドレスを入力してください。")]
    [EmailAddress(ErrorMessage = "有効なメールアドレスを入力してください。")]
    [RegularExpression(@"^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$", ErrorMessage = "有効なメールアドレスを入力してください。")]

    public string EmailAdress { get; set; }

    [Required(ErrorMessage = "メッセージを入力してください。")]
    public string Message { get; set; }

}

Controllers/ContactsController.cs

using Microsoft.AspNetCore.Mvc;
using MimeKit;
using System.Diagnostics;
using WebApplication1.Models;
using MimeKit;
using MailKit.Net.Smtp;


namespace WebApplication1.Controllers
{
    public class ContactsController : Controller
    {
        // GET: Contacts/Create
        public IActionResult Create()
        {
            return View();
        }

        // POST: Contacts/Create
        // To protect from overposting attacks, enable the specific properties you want to bind to.
        // For more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Create([Bind("Name,EmailAdress,Message")] Contact contact)
        {
            if (ModelState.IsValid)
            {
                try
                {
                    var message = new MimeMessage();
                    message.From.Add(new MailboxAddress("送信者名", contact.EmailAdress));
                    message.To.Add(new MailboxAddress("管理者名", "admin@example.com"));
                    message.Subject = "お問い合わせがありました";

                    message.Body = new TextPart("plain")
                    {
                        Text = $"お名前:{contact.Name}\nメールアドレス:{contact.EmailAdress}\nメッセージ:{contact.Message}"
                    };

                    using (var client = new MailKit.Net.Smtp.SmtpClient())
                    {
                        await client.ConnectAsync("localhost", 1025, false);
                        await client.SendAsync(message);
                        await client.DisconnectAsync(true);
                    }

                    return RedirectToAction(nameof(Index), "Home");
                }
                catch (Exception ex)
                {
                    ModelState.AddModelError("", "メールの送信中にエラーが発生しました。");
                    return View(contact);
                }
            }

            return View(contact);
        }
    }
}

Views/Contacts/Create.cshtml

@model Contact

@{
    ViewData["Title"] = "お問い合わせ";
}
<div class="container">
    <h1>@ViewData["Title"]</h1>

    <h4>お問い合わせ内容を下記フォームに記載して送信してください。</h4>
    <hr />
    <div class="row">
        <div class="col-md-4">
            <form asp-action="Create">
                <div asp-validation-summary="ModelOnly" class="text-danger"></div>
                <div class="form-group">
                    <label asp-for="Name" class="control-label"></label>
                    <input asp-for="Name" class="form-control" />
                    <span asp-validation-for="Name" class="text-danger"></span>
                </div>
                <div class="form-group">
                    <label asp-for="EmailAdress" class="control-label"></label>
                    <input asp-for="EmailAdress" class="form-control" />
                    <span asp-validation-for="EmailAdress" class="text-danger"></span>
                </div>
                <div class="form-group">
                    <label asp-for="Message" class="control-label"></label>
                    <textarea asp-for="Message" class="form-control" rows="4"></textarea>
                    <span asp-validation-for="Message" class="text-danger"></span>
                </div>
                <div class="form-group">
                    <input type="submit" value="送信" class="btn btn-primary mt-3" />
                </div>
            </form>
        </div>
    </div>
</div>

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}

WSL2(Ubuntu)を起動:
https://learn.microsoft.com/ja-jp/windows/wsl/install

Ubuntuにdockerをインストール:
https://kinsta.com/jp/blog/install-docker-ubuntu/

Docker HubからMailpitのDockerイメージを取得:
https://hub.docker.com/r/axllent/mailpit

sudo docker pull axllent/mailpit

新しい Docker コンテナを作成:

sudo docker run -d \
--name=mailpit \
--restart unless-stopped \
-p 8025:8025 \
-p 1025:1025 \
axllent/mailpit

(2回目以降)コンテナの再起動:

sudo docker start mailpit

MailpitがDockerコンテナとして起動され、ポート8025でWebインターフェースにアクセスできるようになります。また、SMTPサーバーはポート1025で受信を待ち受けます。
http://localhost:8025/

アプリケーションを起動:

送信を押下:

Mailpitで受信できました。

Dockerコンテナを停止:

sudo docker stop mailpit

Discussion