You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 02:10:53