无法向带有斯堪的纳维亚字符的地址发送电子邮件 [英] Cannot send emails to addresses with Scandinavian characters

查看:32
本文介绍了无法向带有斯堪的纳维亚字符的地址发送电子邮件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用 SmtpClientMailMessageMailAddress 类,我无法发送到电子邮件地址,例如 å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(Boolean allowUnicode)

在 System.Net.Mail.MailAddress.Encode(Int32 charsConsumed, Boolean允许Unicode)

在 System.Net.Mail.MailAddressCollection.Encode(Int32charsConsumed, Boolean allowUnicode)在 System.Net.Mail.Message.PrepareHeaders(Boolean sendEnvelope,布尔值allowUnicode)在 System.Net.Mail.Message.Send(BaseWriter writer, BooleansendEnvelope,布尔值allowUnicode)在 System.Net.Mail.SmtpClient.Send(MailMessage message)

我的主题/正文中的这些字符没问题,但电子邮件地址中的这些字符不行.

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

我一直在挖掘 .Net 源代码,但没有真正得到任何地方.我找到了一个 ServerSupportsEai 属性,Google 告诉我 EAI 代表电子邮件地址国际化 (https://www.rfc-editor.org/rfc/rfc5336)但目前还不清楚这是否是我的代码中的限制,或者我正在与之交谈的特定服务器没有支持这个...因为我使用测试服务器来避免向毫无戒心的瑞典人发送电子邮件!

有人可以帮我解决这个问题 - .Net 是否支持这一点,如果支持的话,如果我的客户端代码应该做些什么来启用它呢?

解决方案

能够根据RFC6531 客户端和服务器都需要支持.

如果您使用 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",支持UTF8吗?");smtp.Send(message);}

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

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

allowUnicode 布尔值由 Send 方法提供:

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

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

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

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

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

220 smtp.gmail.com ESMTP hx10sm19521922wjb.25 - gsmtpEHLO 富巴250-smtp.gmail.com 为您服务,[2001:FFF:8bef:1:34d6:a247:FFFF:4620]250 码 35882577250-8BITMIME250-STARTTLS250 增强状态代码250-流水线250 块250 SMTPUTF8

注意最后一行:它保存了我们需要的 SMTPUTF8

tl;博士

为了能够在电子邮件地址中使用国际字符,请确保将 DeliveryFormat 设置为 SmtpDeliveryFormat.International 并使用支持 SMTPUTF8 扩展的 smtp 服务器并对其进行广告在其 EHLO 命令中.

Using SmtpClient, MailMessage and MailAddress classes, I cannot send to email addresses such as åbc.def@domain.se. I get the error/exceptions as shown below:

An invalid character was found in the mail header: 'å'.

--------------------------- Error sending email --------------------------- System.Net.Mail.SmtpException: The client or server is only configured for E-mail addresses with ASCII local-parts: åbc.def@domain.se.

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

at System.Net.Mail.MailAddress.GetAddress(Boolean allowUnicode)

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

at System.Net.Mail.MailAddressCollection.Encode(Int32 charsConsumed, Boolean allowUnicode) at System.Net.Mail.Message.PrepareHeaders(Boolean sendEnvelope, Boolean allowUnicode) at System.Net.Mail.Message.Send(BaseWriter writer, Boolean sendEnvelope, Boolean allowUnicode) at System.Net.Mail.SmtpClient.Send(MailMessage message)

These characters in my subject/body are fine, but not in email addresses.

I've tried setting SmtpClient.DeliveryMethod = SmtpDeliveryFormat.International, or MailMessage.HeadersEncoding = Encoding.Unicode (or UTF8) and it doesn't seem to change anything. These are real email addresses of people we need to communicate with so it's a bit of a problem.

I have been digging through the .Net source code but not really gotten anywhere. I tracked down a ServerSupportsEai property, and Google tells me EAI stands for Email Address Internationalisation (https://www.rfc-editor.org/rfc/rfc5336) but it's fairly unclear if this is a limitation in my code, or if the specific server I'm talking to just doesn't support this... since I'm using a test server to avoid sending emails to unsuspecting Swedish people!

Can someone help me clear this up - does .Net support this, if so what if anything should my client code do to enable it?

解决方案

To be able to to send UTF-8 characters according to RFC6531 both client and server need to support it.

If you use the .NET implementation of SmtpClient you'll need to target framework version 4.5 because that implementation supports the SMTPUTF8 extension.

If you set the DeliveryFormat property you have done what is needed for your client to support UTF8 characters:

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);
}

If we reverse-engineer the Send method we can easily follow the stack-trace from your question. You'll find this implementation:

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

That allowUnicode boolean is being supplied from the Send method:

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

Now here comes the server in the picture. When does the private boolean ServerSupportsEai becomes true? It turns out that on sending the EHLO command the SmptConnection calls ParseExtensions:

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

If you want to know upfront if your mail server is supporting that extension you can simply connect with a telnet client (I use putty) to your smtp server and send the EHLO somename command and inspect the results.

Connecting to smtp.gmail.comon port 587 gives me this output:

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

Notice the last line: it holds our required SMTPUTF8

tl;dr

To be able to use international characters in the emailaddres make sure to set the DeliveryFormatto SmtpDeliveryFormat.International and use an smtp server that supports the SMTPUTF8 extension and advertises it in its EHLO command.

这篇关于无法向带有斯堪的纳维亚字符的地址发送电子邮件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆