问题描述
使用 SmtpClient
, MailMessage
和 MailAddress
我不能发送到电子邮件地址,如å[email protected]。我收到错误/例外,如下所示:
我的主题/正文中的这些字符没有电子邮件地址。
我已经尝试设置 SmtpClient.DeliveryMethod = SmtpDeliveryFormat.International
或 MailMessage.HeadersEncoding = Encoding.Unicode
(或 UTF8
),似乎没有任何改变。这些是我们需要沟通的人的真实电子邮件地址,所以这是一个问题。
我一直在挖掘.Net源代码,但没有真正得到任何地方。我跟踪了一个 ServerSupportsEai
属性,Google告诉我,EAI代表电子邮件地址国际化()但是,如果这是我的代码中的限制,或者如果我正在谈论的特定服务器不是 t支持这个...因为我使用测试服务器,以避免发送电子邮件到不知情的瑞典人!
有人可以帮助我清除这一点.Net支持这个,如果是的话,我的客户端代码是否应该启用它?
为了能够发送UTF-8根据,客户端和服务器的字符都需要支持。
如果您使用 SmtpClient
的.NET实现,则需要定位框架版本4.5,因为该实现支持SMTPUTF8扩展
如果您设置了您已经完成了您的客户端支持UTF8字符所需的属性:使用(var smtp = new SmtpClient())
{
smtp.DeliveryFormat = SmtpDeliveryFormat.International ;
var message = new MailMessage(
[email protected],
ëçïƒÖ@example.com,
UTF8,
是否支持UTF8?);
smtp.Send(message);
}
如果我们对发送
方法,我们可以轻松地从您的问题跟踪堆栈跟踪。你会发现这个实现:
if(!allowUnicode&& MimeBasePart.IsAscii(this.userName,true) )
{
throw new SmtpException(SR.GetString(SmtpNonAsciiUserNotSupported,new object []
{
this.Address
}));
}
那个 allowUnicode
boolean由发送
方法提供:
if(this.DeliveryMethod == SmtpDeliveryMethod.Network)
{
return this.ServerSupportsEai&& this.DeliveryFormat == SmtpDeliveryFormat.International;
}
现在这里是图片中的服务器。私人布尔值 ServerSupportsEai
何时变为true?事实证明,在发送 EHLO
命令 SmptConnection
调用 ParseExtensions $ c $如果(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 - gsmtp
EHLO fubar
250-smtp.gmail.com在您服务,[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; dr
为了能够在电子邮件地址中使用国际字符,请确保设置 DeliveryFormat
到 SmtpDeliveryFormat.International
并使用smtp服务器su输入SMTPUTF8扩展名,并在其 EHLO
命令中进行通告。
Using SmtpClient
, MailMessage
and MailAddress
classes, I cannot send to email addresses such as å[email protected]. I get the error/exceptions as shown below:
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://tools.ietf.org/html/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(
"[email protected]",
"ëçïƒÖ@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.com
on 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 DeliveryFormat
to SmtpDeliveryFormat.International
and use an smtp server that supports the SMTPUTF8 extension and advertises it in its EHLO
command.
这篇关于不能发送电子邮件到斯堪的纳维亚文字的地址的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!