みんなの洋楽ランキングを.NET Coreに絶賛移行中でMacBook Airのみで開発しています。.Net Core3.0ではWindows Formも対応するみたいでなかなか最強感出てきましたね!ASP.NET CoreはScalaの1.7倍のパフォーマンスを出すそうです。
www.ageofascent.com
タイトル通り「.NET CoreでSystem.Net.Mail.SmtpClientが使えなくなった」です。
.NET CoreからSystem.Net.Mail.SmtpClientでなくMimeKitが推奨されましたのでそのメモ。結構この記事は多いのですが、デバッグ時にSSL推奨の影響でエラーになっちゃったりするんでその対応を追記します。
MimeKitとは?
github.com
オープンソースのメールライブラリです。公式がこう発表しています。
「SmtpClientとそのタイプのネットワークは設計が不十分であり、代わりに MailKitを使うことを強く推奨する」
という感じです。
MimeKitをインストール
バージョンは以下で確認してくださいGithubの最新は2.02だった。なぜ?
www.nuget.org
以下のコマンドで追加
dotnet add package MailKit --version 2.0.3
csprojに
<PackageReference Include="MailKit" Version="2.0.3" />
を追加して
dotnet restore
でも良いです。
使い方
usingと生成
using MimeKit; var emailMessage = new MimeMessage ();
送信元とユーザー名を設定
emailMessage.From.Add (new MailboxAddress ("ユーザー名", "送信元"));
送信先の設定
emailMessage.To.Add (new MailboxAddress ( "送信先"));
件名と本文を設定
emailMessage.Subject = "件名"; emailMessage.Body = new TextPart ("plain") { Text = "本文" };
SMTPサーバに接続
var client = new SmtpClient(); await client.ConnectAsync("smtp.test.net", 587, SecureSocketOptions.SslOnConnect);
SMTPサーバ認証IDとパスワード)
await client.AuthenticateAsync("SMTPサーバ認証ID", "パスワード");
メールを送信
await client.SendAsync(emailMessage);
SMTPサーバ接続を切る
await client.DisconnectAsync(true);
処理はこれで終了です。ですが、開発中にSSLにしていないとエラーになります。
エラーになるコードは以下です。
var emailMessage = new MimeMessage (); //と await client.ConnectAsync("smtp.test.net", 587, SecureSocketOptions.SslOnConnect);
で以下のエラーが発生します。
SslHandshakeException: An error occurred while attempting to establish an SSL or TLS connection.
SSL接続が出来ないってことですね。なので対策のため、生成前に証明書検証用コールバックを設定します。
ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true; var emailMessage = new MimeMessage ();
SecureSocketOptionsはStartTlsを設定します。StartTlsは受信側がTLS/SSLに対応していれば暗号化して送り、されていなければ平文で送るオプションです。
await client.ConnectAsync("smtp.test.net", 587, SecureSocketOptions.StartTls);
ちなみにGmailは以下のコードにメールアドレスとパスワードを設定すればよいです。
await client.AuthenticateAsync("SMTPサーバ認証ID", "パスワード");
ざっと通しで作ったので確認してみてください。
using System.Linq; using System.Net; using System.Threading.Tasks; using MailKit.Net.Smtp; using MailKit.Security; using MimeKit; namespace Mail { public class MailManager { public string UserName { get; set; } public string PassWord { get; set; } public string From { get; set; } public string To { get; set; } public string Subject { get; set; } public string Body { get; set; } public string Host { get; set; } public int Port { get; set; } public async Task SendEmailAsync () { #if DEBUG ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true; #endif var emailMessage = new MimeMessage (); emailMessage.From.Add (new MailboxAddress (this.UserName, this.From)); emailMessage.To.Add (new MailboxAddress (this.To)); emailMessage.Subject = this.Subject; emailMessage.Body = new TextPart ("plain") { Text = this.Body }; using (var client = new SmtpClient ()) { #if DEBUG await client.ConnectAsync (this.Host, this.Port, SecureSocketOptions.StartTls); #else await client.ConnectAsync (this.Host, this.Port, SecureSocketOptions.SslOnConnect); #endif await client.AuthenticateAsync (this.UserName, this.PassWord); await client.SendAsync (emailMessage); await client.DisconnectAsync (true); } } } }
最低限必要なものはプロパティで用意しているので、設定すれば動くと思います。
async、awaitが標準になり使い勝手も変わらないので結構楽でよいですね!