【C#】MailKitを使用してメールを送信する方法

目次

概要

.NETでメール送信機能を実装する場合、標準ライブラリの System.Net.Mail.SmtpClient は現在「旧式(Obsolete)」扱いとなっており、マイクロソフトはオープンソースライブラリである MailKit の使用を推奨しています。 MailKitを使用することで、最新のセキュリティプロトコルに対応したSMTP送信、HTMLメールの作成、添付ファイルの処理などを簡単かつ安全に行うことができます。ここでは、宛先(To, Cc, Bcc)を柔軟に設定できるラッパークラスを作成し、SMTPサーバー経由でテキストメールを送信する実装を紹介します。

仕様(入出力)

  • 入力: 送信元アドレス、宛先リスト(To/Cc/Bcc)、件名、本文。
  • 出力: SMTPサーバーへの接続およびメール送信実行。
  • 前提: .NET Standard 2.0以上。NuGetパッケージ MailKit のインストールが必要。

パッケージ導入

以下のコマンドを実行してライブラリを追加します。

dotnet add package MailKit

基本の使い方

MimeMessage オブジェクトを作成して宛先や本文を設定し、SmtpClient (MailKit.Net.Smtp) を使用して送信します。接続、認証、送信、切断の流れが基本となります。

var message = new MimeMessage();
message.From.Add(new MailboxAddress("Sender Name", "sender@example.com"));
message.To.Add(new MailboxAddress("", "recipient@example.com"));
message.Subject = "Hello";
message.Body = new TextPart("plain") { Text = "Email content" };

using (var client = new SmtpClient())
{
    await client.ConnectAsync("smtp.server.com", 587, SecureSocketOptions.StartTls);
    await client.AuthenticateAsync("user", "password");
    await client.SendAsync(message);
    await client.DisconnectAsync(true);
}

コード全文

ユーザーの入力コードをベースに、To/Cc/Bccの複数指定に対応し、エラーハンドリングとリソース破棄(using)を適切に実装した完全なコードです。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using MailKit.Net.Smtp;
using MailKit.Security;
using MimeKit;

class Program
{
    static async Task Main()
    {
        // 送信情報の構築
        var mailService = new EmailService
        {
            From = "my_account@example.com", // 送信元
            Subject = "テストメール送信",
            Body = "これはMailKitを使用したテスト送信です。\nC#から送信しています。"
        };

        // 宛先設定(リストで追加)
        mailService.To.Add("mori01@example.com");
        mailService.To.Add("mori02@example.com");
        
        // CC/BCC設定(必要に応じて)
        mailService.Cc.Add("manager@example.com");

        Console.WriteLine("メール送信を開始します...");

        try
        {
            await mailService.SendMailAsync();
            Console.WriteLine("送信が完了しました。");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"送信エラー: {ex.Message}");
        }
    }
}

// メール送信機能をカプセル化したクラス
public class EmailService
{
    // SMTPサーバー設定(定数や設定ファイルから読み込むのが一般的)
    private const string SmtpHost = "smtp.example.com";
    private const int SmtpPort = 587;
    private const string SmtpUser = "your_username";
    private const string SmtpPass = "your_password";

    public List<string> To { get; set; } = new List<string>();
    public List<string> Cc { get; set; } = new List<string>();
    public List<string> Bcc { get; set; } = new List<string>();
    public string From { get; set; } = string.Empty;
    public string Subject { get; set; } = string.Empty;
    public string Body { get; set; } = string.Empty;

    public async Task SendMailAsync()
    {
        // 1. メッセージの作成
        var message = new MimeMessage();

        // 送信元の設定
        message.From.Add(new MailboxAddress(GetNameFromAddress(From), From));

        // 宛先(To)の追加
        foreach (var addr in To)
        {
            message.To.Add(new MailboxAddress(GetNameFromAddress(addr), addr));
        }

        // Ccの追加
        foreach (var addr in Cc)
        {
            message.Cc.Add(new MailboxAddress(GetNameFromAddress(addr), addr));
        }

        // Bccの追加
        foreach (var addr in Bcc)
        {
            message.Bcc.Add(new MailboxAddress(GetNameFromAddress(addr), addr));
        }

        message.Subject = Subject;

        // 本文の設定(TextPartを使用)
        // HTMLメールの場合は "html" を指定し、BodyBuilderを使うと便利です
        var builder = new BodyBuilder();
        builder.TextBody = Body;
        message.Body = builder.ToMessageBody();

        // 2. SMTPクライアントによる送信
        using (var client = new SmtpClient())
        {
            // 接続
            // 第3引数でSSL/TLSの自動ネゴシエーションを指定
            await client.ConnectAsync(SmtpHost, SmtpPort, SecureSocketOptions.Auto);

            // 認証(ユーザー名とパスワード)
            // Gmail等の場合、通常のパスワードではなく「アプリパスワード」が必要な場合があります
            await client.AuthenticateAsync(SmtpUser, SmtpPass);

            // 送信
            await client.SendAsync(message);

            // 切断
            await client.DisconnectAsync(true);
        }
    }

    // メールアドレスから表示名(@より前の部分)を簡易的に抽出するヘルパー
    private static string GetNameFromAddress(string mailAddress)
    {
        if (string.IsNullOrEmpty(mailAddress)) return string.Empty;
        
        int atIndex = mailAddress.IndexOf('@');
        return atIndex > 0 ? mailAddress.Substring(0, atIndex) : mailAddress;
    }
}

カスタムポイント

  • Gmailでの送信: Gmailを使用する場合、セキュリティ設定で「アプリパスワード」を生成し、それをパスワードとして使用する必要があります。また、ポートは 587 (StartTLS) または 465 (SSL) を使用します。
  • HTMLメール: builder.TextBody の代わりに builder.HtmlBody にHTMLタグを含む文字列を設定することで、装飾されたメールを送信可能です。
  • 添付ファイル: builder.Attachments.Add("path/to/file.pdf"); を追加するだけでファイルを添付できます。

注意点

  1. ポート番号とセキュリティ: 一般的にサブミッションポート 587SecureSocketOptions.StartTls)または 465SecureSocketOptions.SslOnConnect)が使用されます。25 番ポートは多くのプロバイダでブロックされているため避けてください。
  2. 例外処理: ネットワーク障害や認証エラーは頻繁に起こり得ます。try-catch ブロックで SmtpCommandExceptionProtocolException を捕捉し、適切なログ出力を行ってください。
  3. Fromアドレスの制限: 多くのSMTPサーバーでは、認証に使用したアカウント以外のメールアドレスを From に設定することを禁止しています(なりすまし防止のため)。

まとめ

.NETでメール送信を行う際は、廃止予定の標準クラスではなく MailKit を採用することで、モダンなセキュリティ基準に準拠した実装が可能になります。宛先リストのループ処理やMimeMessageの構築を専用クラスにカプセル化することで、メインの処理コードをシンプルに保つことができ、再利用性も高まります。SMTPサーバーの設定情報(ホスト、ポート、認証情報)は機密情報であるため、実際の開発ではソースコードに直書きせず、環境変数やセキュアな構成管理システムから読み込むように設計してください。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次