Апостроф в адресе электронной почты вызывает SmtpException

Наше бизнес-приложение обслуживает многие организации, и некоторые из них имеют апострофы в адресе электронной почты (локальная часть), что технически допустимо.

Однако я не могу отправлять электронные письма, если адрес электронной почты FROM или TO содержит в них апостроф (локальная часть), как в этом примере С#:

    private const string SMTP_HOST = "localhost";
    public static void CreateCopyMessage2()
    {
//      var from = new MailAddress("john.o'[email protected]", "John O'Connor");
        var from = new MailAddress("[email protected]", "John Smith");

        var to = new MailAddress("jane.o'[email protected]", "Jane O'Leary");
//      var to = new MailAddress("[email protected]", "Jane Smith");


        var message = new MailMessage(from, to) {
            Subject = "Email Subject",
            Body = "Email Body Text"
        };

        SmtpClient client = new SmtpClient(SMTP_HOST) {
            Credentials = CredentialCache.DefaultNetworkCredentials
        };

        try
        {
            client.Send(message);
        }
        catch (SmtpException ex)
        {
            Console.WriteLine($"Exception caught: {ex}");
        }
    }

Сведения об исключении, когда to адрес электронной почты содержит апостроф:

System.Net.Mail.SmtpException: Syntax error in parameters or arguments. The server response was: Error in parameters. Syntax:{RCPT TO:<address> [SIZE=msgSize]}
   at System.Net.Mail.RecipientCommand.CheckResponse(SmtpStatusCode statusCode, String response)
   at System.Net.Mail.SmtpTransport.SendMail(MailAddress sender, MailAddressCollection recipients, String deliveryNotify, Boolean allowUnicode, SmtpFailedRecipientException& exception)
   at System.Net.Mail.SmtpClient.Send(MailMessage message)
   at EmailWithApostropheTest.Program.Main() in ....\Program.cs:line 65

Сведения об исключении, когда from адрес электронной почты содержит апостроф:

System.Net.Mail.SmtpException: Syntax error in parameters or arguments. The server response was: Error in parameters. Syntax:{MAIL FROM:<address> [SIZE=msgSize] [BODY=8BITMIME]}
   at System.Net.Mail.MailCommand.CheckResponse(SmtpStatusCode statusCode, String response)
   at System.Net.Mail.MailCommand.Send(SmtpConnection conn, Byte[] command, MailAddress from, Boolean allowUnicode)
   at System.Net.Mail.SmtpTransport.SendMail(MailAddress sender, MailAddressCollection recipients, String deliveryNotify, Boolean allowUnicode, SmtpFailedRecipientException& exception)
   at System.Net.Mail.SmtpClient.Send(MailMessage message)
   at EmailWithApostropheTest.Program.Main() in ....\Program.cs:line 65

Электронные письма хороши, если они не содержат апострофа. Любые советы будут оценены.

РЕДАКТИРОВАТЬ: @JamesThorpe прокомментировал ниже тестирование с помощью telnet. У меня есть два производственных сервера, которые используют hmailserver и mdaemon, а также среда разработки, в которой используется собственная корзина smtp. Всем трем удалось принять и ретранслировать электронные письма, содержащие апострофы, а мой собственный (в отладчике) никогда не получал команду (MAIL FROM/RCPT TO), которая содержала адрес электронной почты с апострофом при использовании SMTPClient, поэтому я уверен, что это является проблемой .NET SMTPClient.

Вот примеры телнетов, которые работали (test.com — это заполнитель для того, что я на самом деле использовал):

220 test.com ESMTP Mon, 13 Nov 2017 17:30:29 +0000
HELO test.com
250 test.com Hello test.com [127.0.0.1], pleased to meet you
MAIL FROM:noreply.o'[email protected]
250 2.1.0 Sender OK
RCPT TO:[email protected]
250 2.1.5 Recipient OK
DATA
354 Enter mail, end with <CRLF>.<CRLF>
test 123 test 123 from elms
.
250 2.6.0 Ok, message saved



220 test2.net ESMTP
HELO test2.net
250 Hello.
MAIL FROM:[email protected]
250 OK
RCPT TO:john.o'[email protected]
250 OK
DATA
354 OK, send.
Test 123
.
250 Queued (4.531 seconds)
MAIL FROM:test.o'[email protected]
250 OK
RCPT TO:[email protected]
250 OK
DATA
354 OK, send.
test123
test 123
.
250 Queued (3.203 seconds)

Спасибо, Крис.


person Chris Walsh    schedule 13.11.2017    source источник
comment
Похоже, проблема связана с тем почтовым сервером, который вы используете, а не с вашим кодом. Вы можете отправить электронное письмо с помощью telnet чтобы проверить это и убедиться, что .NET не искажает адреса внутри себя.   -  person James Thorpe    schedule 13.11.2017
comment
В наших двух производственных средах мы используем mdaemon и hmailserver, а моя среда разработки использует мой собственный фиктивный SMTP-сервер, который получает команды MAIL FROM и RCPT TO, но только если они этого не делают. содержит апостроф (он не получает ни того, ни другого, если присутствует адрес электронной почты на основе апострофа), поэтому я не думаю, что это сторона SMTP-сервера.   -  person Chris Walsh    schedule 13.11.2017
comment
Я попробую telnet, не подумал об этом... Итак, в моей среде разработки я действительно получаю ответ об ошибке: MAIL FROM: chris.o'[email protected] 501 Error in parameters. Syntax:{MAIL FROM:<address> [SIZE=msgSize] [BODY=8BITMIME]}. Конечно, большинство почтовых серверов должны принимать адрес электронной почты с апострофом, если он является частью RFC, а не одним из наиболее неясных форматов электронной почты?   -  person Chris Walsh    schedule 13.11.2017
comment
Значит, он не работает и в вашей производственной среде? Вы упомянули, что ваш разработчик — это мой собственный фиктивный SMTP-сервер — проблема ограничивается только этим?   -  person James Thorpe    schedule 13.11.2017
comment
Оба производственных сервера смогли отправить электронное письмо с апострофами через telnet. (Они оказались в нашем спам-фильтре из-за минимальной информации в заголовке электронной почты, но я отправил их туда, и они попали в мой почтовый ящик). Я уверен, что это как-то связано с SMTPClient, так как все три среды работали до определенного момента через telnet. Я добавлю свои выводы telnet в конец моего вопроса.   -  person Chris Walsh    schedule 13.11.2017
comment
Я опубликовал эту проблему около 18 месяцев назад, и я все еще сталкиваюсь с проблемой (производство и разработка) - и для уточнения, исключение возникает перед любым общением с MTA, поэтому оно должно быть внутренним для .NET Framework.   -  person Chris Walsh    schedule 30.05.2019


Ответы (1)


Если вы установите международный формат доставки, он должен работать. Что-то типа:

    SmtpClient client = new SmtpClient(SMTP_HOST) {
        Credentials = CredentialCache.DefaultNetworkCredentials,
        DeliveryFormat = SmtpDeliveryFormat.International
    };
person N. Little    schedule 18.09.2019