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

使用SmtpClientMailMessageMailAddress类,我无法发送到电子邮件地址,例如åbc.def@domain.se。 我得到错误/exception,如下所示:

邮件标题中找到了无效字符:’å’。

—————————发送邮件时出错——————– ——- 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是否支持这一点,如果是这样,如果我的客户端代码应该做什么来启用它呢?

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

如果您使用SmtpClient的.NET实现,则需要定位框架版本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); } 

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

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

那个allowUnicode boolean是从Send方法提供的:

 if (this.DeliveryMethod == SmtpDeliveryMethod.Network) { return this.ServerSupportsEai && this.DeliveryFormat == SmtpDeliveryFormat.International; } 

现在来到图片中的服务器。 私有布尔ServerSupportsEai变为true? 事实certificate,在发送EHLO命令时, SmptConnection调用ParseExtensions

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

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

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

 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 

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

TL;博士

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