ポイント
- 送信アドレス誤りは同イントラ内限定で検出できた。別ドメインへのメール送信エラーは制御出来ない。
- 複数のアドレスに送信するときにアドレス誤りを検出するには、SmtpFailedRedipientsException と SmtpFailedRecipientException の両方でキャッチする必要がある。
- 1 つのアドレスにだけ送信する場合は、SmtpFailedRecipientException のみでよい。
- 送信できなかったメールアドレスは、SmtpFailedRecipientException.FailedRecipient に格納されている。
- Host、Port、userName、password に原因がある (つまりサーバに接続できない) 場合は SmtpException でキャッチできる。
他のポイント
- メールを送るには、MailMessage クラス、SmtpClient クラスの 2 つが必要
- MailMessage クラスはメール自体を扱うクラス
- From、To、CC、BCC、添付ファイル、件名、本文などを扱う。
- メールアドレスの追加は、MailAddress クラスにメールアドレス文字列を渡してインスタンス化したものを使う。
- SmtpClient クラスはメールを送るときの認証情報を扱うクラス。
- SMTP サーバ名、ポート番号、ユーザー名、パスワード、SSL の使用などを扱う。
- ユーザ名、パスワード の追加は、NetworkCredential クラスにユーザー名、パスワード文字列渡してインスタンス化したものを使う。
ソースコード
の環境、ファイルは同じです。リンク先の投稿のファイルを編集しました。
public ActionResult Index()
{
return View();
}
[HttpPost, ActionName("Index")]
[ValidateAntiForgeryToken]
public ActionResult IndexExec()
{
//Hotmailでメールを送信する
//MailMessageの作成
var from = "xxxxx@hotmail.co.jp";
var to = "yyyyy@gmail.com";
var to2 = "zzzzz@gmail.com";
var subject = "テスト";
var body = "このメールは、テストです。";
MailMessage msg = new MailMessage();
msg.From = new MailAddress(from);
msg.To.Add(new MailAddress(to));
msg.To.Add(new MailAddress(to2));
msg.Subject = subject;
msg.Body = body;
SmtpClient sc = new SmtpClient();
//SMTPサーバーなどを設定する
sc.Host = "smtp.live.com";
sc.Port = 587;
sc.DeliveryMethod = SmtpDeliveryMethod.Network;
//ユーザー名とパスワードを設定する
var userName = "xxxxx@hotmail.co.jp";
var password = "zzzzz";
sc.Credentials = new NetworkCredential(userName, password);
//SSLを使用する
sc.EnableSsl = true;
// 次のメール送信エラーハンドリング
// - サーバ接続エラー
// - 送信アドレス誤りエラー(同イントラ内。別ドメインへのメール送信エラーは制御出来ない)
try
{
//メッセージを送信する
sc.Send(msg);
ViewBag.Message = "送信成功";
}
catch (SmtpFailedRecipientsException e)
{
// 送信アドレス誤りエラーが2件以上の場合
// 誤ったアドレス分、例外を発生させる。
// 正しいアドレスには、メールが送られる。
var message = "SmtpFailedRecipientsException 発生で2件以上送信アドレス誤りエラー: ";
foreach (var item in e.InnerExceptions)
{
message = message + " " + item.FailedRecipient;
}
ViewBag.Message = message;
}
catch (SmtpFailedRecipientException e)
{
// 送信アドレス誤りエラーが1件のみの場合
ViewBag.Message = "SmtpFailedRecipientException 発生で1件だけ送信アドレス誤りエラー: " + e.Message;
}
catch (SmtpException e)
{
// SmtpException クラス (System.Net.Mail) https://msdn.microsoft.com/ja-jp/library/system.net.mail.smtpexception(v=vs.110).aspx
// Host、Port、userName、Password に原因がある
// Host が原因ならば、SmtpException.InnerException に格納された WebException
// Port が原因ならば、SmtpException.InnerException.InnerException に格納された SocketException
// userName、password が原因ならば、SmtpException
// WebException、SocketException を個別にキャッチすることはできない。
ViewBag.Message = "SmtpException 発生でサーバ接続エラー: " + e.Message;
}
finally
{
//後始末
msg.Dispose();
sc.Dispose();
}
return View();
}
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="メール送信" class="btn btn-default" />
</div>
</div>
</div>
}
<h3>@ViewBag.Message</h3>
実行した時のエラーメッセージ
パスワードを間違えた時
SmtpException 発生でサーバ接続エラー: メールボックスが使用できません。 サーバーの応答:5.7.3 Requested action aborted; user not authenticated
おわりに
メール送受信時のエラーは、メールが相手に届いたかどうか確認できたら素晴らしいのに、、、と思うのですけれどもメールが送信元のサーバーをはなれてしまうためどうにもなりません><。
思ったよりもサポートできる範囲が限られてしまう印象ですの。
以上です。
