ASP.NET Core 6使用含变音符号邮箱发送邮件抛异常求助
问题:发送含变音符号的邮箱地址时触发SmtpException
我在使用通用的EmailSender服务发送邮件时,当收件邮箱为test@pläne.de这类包含变音符号(ä、ü、ö)的地址时,出现以下未处理异常:
An unhandled exception occurred while processing the request.
SmtpException: Mailbox unavailable. The server response was: Requested action not taken: mailbox unavailable
System.Net.Mail.MailCommand.CheckResponse(SmtpStatusCode statusCode, string response)
尝试用IdnMapping处理但未成功,求可行解决方案。
原代码片段
public Task SendEmailAsync(string email, string subject, string htmlMessage) { var smtp = new ConfigurationBuilder().AddJsonFile("appsettings.json").Build().GetSection("Smtp"); string fromMail = smtp["FromAddress"]; string fromPassword = smtp["Password"]; // string userName = smtp["UserName"]; MailMessage message = new MailMessage(); // idn mapping IdnMapping idn = new IdnMapping(); message.From = new MailAddress(fromMail); // message.From = new MailAddress(idn.GetAscii(fromMail)); message.Subject = subject; message.To.Add(new MailAddress(email)); message.Body = "<html><body> " + htmlMessage + " </body></html>"; message.IsBodyHtml = true; var smtpClient = new SmtpClient(smtp["Server"]) { Port = Convert.ToInt32(smtp["Port"]), //Credentials = new NetworkCredential(userName, fromPassword), Credentials = new NetworkCredential(fromMail, fromPassword), //Credentials = new NetworkCredential(idn.GetAscii(fromMail), fromPassword), EnableSsl = true, }; return smtpClient.SendMailAsync(message); }
解决方案
核心处理逻辑
问题出在未正确拆分邮箱的本地部分和域名部分进行IDN转换:邮箱的域名部分必须转换为Punycode(ASCII格式的IDN),而本地部分无需转换(大部分SMTP服务器不支持Unicode本地部分)。之前的尝试仅针对发件人邮箱,且未拆分处理,导致收件人域名的变音符号未被正确转换。
修改后的代码
public Task SendEmailAsync(string email, string subject, string htmlMessage) { var smtp = new ConfigurationBuilder().AddJsonFile("appsettings.json").Build().GetSection("Smtp"); string fromMail = smtp["FromAddress"]; string fromPassword = smtp["Password"]; MailMessage message = new MailMessage(); IdnMapping idn = new IdnMapping(); // 处理发件人邮箱(若发件人域名含变音符号) var fromParts = fromMail.Split('@'); if (fromParts.Length == 2) { string fromLocal = fromParts[0]; string fromDomainAscii = idn.GetAscii(fromParts[1]); message.From = new MailAddress($"{fromLocal}@{fromDomainAscii}"); } else { // 格式错误时 fallback 到原地址 message.From = new MailAddress(fromMail); } // 处理收件人邮箱:拆分本地和域名,转换域名到Punycode var toParts = email.Split('@'); if (toParts.Length == 2) { string toLocal = toParts[0]; string toDomainAscii = idn.GetAscii(toParts[1]); message.To.Add(new MailAddress($"{toLocal}@{toDomainAscii}")); } else { // 格式错误时 fallback 到原地址 message.To.Add(new MailAddress(email)); } message.Subject = subject; message.Body = $"<html><body> {htmlMessage} </body></html>"; message.IsBodyHtml = true; var smtpClient = new SmtpClient(smtp["Server"]) { Port = Convert.ToInt32(smtp["Port"]), // SMTP凭据是否转换取决于服务器要求:若服务器仅支持ASCII用户名,则转换fromMail为Punycode格式 Credentials = new NetworkCredential(fromMail, fromPassword), EnableSsl = true, }; return smtpClient.SendMailAsync(message); }
额外注意事项
- 确认SMTP服务器支持IDN:部分老旧SMTP服务器可能不兼容Punycode格式的域名,此时需联系收件方确认邮箱有效性,或更换支持IDN的SMTP服务。
- .NET版本差异:.NET Core 3.0及以上版本的
MailAddress构造函数会自动处理域名的IDN转换,但手动拆分处理兼容性更好。 - 格式校验:添加邮箱拆分后的长度校验,避免因无效邮箱格式引发新的异常。
内容的提问来源于stack exchange,提问作者Visionz
相关产品推荐
相关产品推荐

