2016-02-02 5 views
8

Используя классы SmtpClient, MailMessage и MailAddress, я не могу отправить адреса электронной почты, такие как å[email protected] Я получаю ошибку/исключения, как показано ниже:Не удается отправить электронные письма по адресам со скандинавскими символами

Недопустимый символ был найден в почтовом заголовке: 'å'.

--------------------------- Ошибка отправки электронной почты --------------- ------------ System.Net.Mail.SmtpException: клиент или сервер настроен только для адресов электронной почты с локальными частями ASCII : å[email protected]

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

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

в System.Net.Mail.MailAddress.Encode (Int32 charsConsumed, булева allowUnicode)

на System.Net.Mail.MailAddressCollection.Encode (Int32 charsConsumed, булева allowUnicode) в System.Net.Mail.Message.PrepareHeaders (Boolean sendEnvelope, Логическое allowUnicode) в System.Net.Mail.Message.Send (BaseWriter писатель, Boolean sendEnvelope, Boolean allowUnicode) на System.Net.Mail.SmtpClient.Send (MailMessage сообщение)

Эти символы в моей теме/тело в порядке, но не в адресах электронной почты.

Я пробовал установить SmtpClient.DeliveryMethod = SmtpDeliveryFormat.International, или MailMessage.HeadersEncoding = Encoding.Unicode (или UTF8), и он ничего не меняет. Это настоящие адреса электронной почты людей, с которыми нам нужно общаться, поэтому это немного проблема.

Я копаю исходный код .Net, но не получил нигде. Я отслеживал свойство ServerSupportsEai, и Google сообщает мне, что EAI означает интернационализацию адресов электронной почты (https://tools.ietf.org/html/rfc5336), но это довольно неясно, является ли это ограничением в моем коде или если конкретный сервер, о котором я говорю, просто не поддерживает это. .. поскольку я использую тестовый сервер, чтобы не отправлять электронные письма не подозревающим шведским людям!

Может кто-нибудь помочь мне разобраться в этом - делает .Net это поддерживает, если да, то что, если что-нибудь должно сделать для моего кода клиента, чтобы включить его?

+0

Я думаю, что проблема может быть не в коде .NET, а в конфигурации вашего почтового сервера. Можете ли вы попробовать использовать другой сервер? – Pikoh

+0

(5336 заменен на 6531/2). Это средство требует, чтобы SMTP-сервер поддерживал SMTPUTF8, попробуйте с Gmail, который делает, если он работает на вашем сервере. –

+0

Спасибо. После битвы с gmail «приложение не использует обновленную защиту и заблокировано». Я тестирую это, хотя я до сих пор не могу отправить реальному человеку очень вежливо –

ответ

9

Чтобы иметь возможность отправлять символы UTF-8 в соответствии с RFC6531, клиент и сервер должны его поддерживать.

Если вы используете .NET-версию SmtpClient, вам необходимо настроить рамочную версию 4.5, поскольку эта реализация поддерживает расширение SMTPUTF8.

Если установить DeliveryFormat свойство, которое вы сделали то, что необходимо для вашего клиента для поддержки UTF8 символов:

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

    var message = new MailMessage(
     "[email protected]", 
     "ëçïƒÖ@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 булевых подаются от метода Send:

if (this.DeliveryMethod == SmtpDeliveryMethod.Network) 
{ 
    return 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 (я использую замазку), чтобы ваш 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 

Обратите внимание на последнюю строку: она держит нашу необходимую SMTPUTF8

Tl; дг

Чтобы иметь возможность использовать международные символы в emailaddres обязательно установите DeliveryFormat в SmtpDeliveryFormat.International и используйте SMTP-сервер, поддерживающий расширение SMTPUTF8, и объявите его в своей команде EHLO.