无法使用斯堪的纳维亚字符向地址发送电子邮件

Mr.*_*Boy 9 .net c# email smtpclient .net-4.5

使用SmtpClient,MailMessageMailAddress班,我无法发送到电子邮件地址,如åbc.def@domain.se.我得到错误/异常,如下所示:

邮件标题中找到了无效字符:'å'.

---------------------------发送电子邮件时出错-------------------- ------- System.Net.Mail.SmtpException:客户端或服务器仅配置为具有ASCII本地部分的电子邮件地址:åbc.def@domain.se.

在System.Net.Mail.MailAddress.GetUser(Boolean allowUnicode)

在System.Net.Mail.MailAddress.GetAddress(布尔allowUnicode)

在System.Net.Mail.MailAddress.Encode(Int32 charsConsumed,Boolean allowUnicode)

System.Net.Mail.Mail.Message.Send上的System.Net.Mail.MailAddressCollection.Encode(Int32 charsConsumed,Boolean allowUnicode)处于System.Net.Mail.Message.PrepareHeaders(Boolean sendEnvelope,Boolean allowUnicode)处(BaseWriter writer,Boolean sendEnvelope) ,System.Net.Mail.SmtpClient.Send(MailMessage消息)中的布尔值allowUnicode)

我的主题/正文中的这些字符很好,但不在电子邮件地址中.

我试过设置SmtpClient.DeliveryMethod = SmtpDeliveryFormat.International,或MailMessage.HeadersEncoding = Encoding.Unicode(或UTF8)它似乎没有改变任何东西.这些是我们需要与之沟通的人的真实电子邮件地址,因此这有点问题.

我一直在挖掘.Net源代码,但并没有真正得到任何东西.我追踪了一个ServerSupportsEai属性,谷歌告诉我EAI代表电子邮件地址国际化(https://tools.ietf.org/html/rfc5336),但我不清楚这是否是我的代码中的限制,或者如果特定的服务器我我正在谈论只是不支持这个......因为我正在使用测试服务器来避免向毫无戒心的瑞典人发送电子邮件!

有人可以帮助我清除这一点 - .Net是否支持这一点,如果是这样,如果我的客户端代码应该做什么来启用它呢?

ren*_*ene 12

为了能够根据RFC6531发送UTF-8字符,客户端和服务器都需要支持它.

如果您使用.NET实现,则SmtpClient需要针对框架版本4.5,因为该实现支持SMTPUTF8扩展.

如果设置了DeliveryFormat属性,则表示您已完成客户端支持UTF8字符所需的操作:

using (var smtp = new SmtpClient())
{
    smtp.DeliveryFormat = SmtpDeliveryFormat.International;

    var message = new MailMessage(
        "my.email@gmail.com",
        "ëçïƒÖ@example.com",
        "UTF8",
        "Is UTF8 supported?");

    smtp.Send(message);
}
Run Code Online (Sandbox Code Playgroud)

如果我们对Send方法进行反向工程,我们可以轻松地从您的问题中跟踪堆栈跟踪.你会发现这个实现:

if (!allowUnicode && !MimeBasePart.IsAscii(this.userName, true))
{
    throw new SmtpException(SR.GetString("SmtpNonAsciiUserNotSupported", new object[]
    {
        this.Address
    }));
}
Run Code Online (Sandbox Code Playgroud)

allowUnicodeSend方法提供了该布尔值:

if (this.DeliveryMethod == SmtpDeliveryMethod.Network)
{
    return this.ServerSupportsEai && this.DeliveryFormat == SmtpDeliveryFormat.International;
}
Run Code Online (Sandbox Code Playgroud)

现在这里是图片中的服务器.私有布尔值何时ServerSupportsEai变为真?事实证明,在发送EHLO命令时SmptConnection调用ParseExtensions:

if (string.Compare(text, 0, "SMTPUTF8", 0, 8, StringComparison.OrdinalIgnoreCase) == 0)
{
    ((SmtpPooledStream)this.pooledStream).serverSupportsEai = true;
}
Run Code Online (Sandbox Code Playgroud)

如果您想知道您的邮件服务器是否支持该扩展,您只需将telnet客户端(我使用putty)连接到您的smtp服务器并发送EHLO somename命令并检查结果.

连接到smtp.gmail.com端口587给我这个输出:

220 smtp.gmail.com ESMTP hx10sm19521922wjb.25 - gsmtp
EHLO fubar
250-smtp.gmail.com at your service, [2001:FFF:8bef:1:34d6:a247:FFFF:4620]
250-SIZE 35882577
250-8BITMIME
250-STARTTLS
250-ENHANCEDSTATUSCODES
250-PIPELINING
250-CHUNKING
250 SMTPUTF8
Run Code Online (Sandbox Code Playgroud)

注意最后一行:它包含我们所需的SMTPUTF8

TL;博士

为了能够在emailaddres中使用国际字符,请确保设置DeliveryFormatSmtpDeliveryFormat.International并使用支持SMTPUTF8扩展名的smtp服务器并在其EHLO命令中通告它.