SmtpClient (.NET) не кодирует почтовый заголовок в соответствии с RFC 2047

Я использую.NET SmtpClient послать электронное письмо, где предмет мог бы содержать символы за пределами диапазона ASCII. RFC 2047 определяет, как почтовый текст должен быть закодирован, когда он содержит специальные символы. Вот пример предмета в почтовом заголовке:

Subject: Votre enregistrement numéro 123

Это должно стать после кодирования к ISO-8859-1:

Subject: =?iso-8859-1?Q?Votre=20enregistrement=20num=E9ro=20123?=

где все специальные символы, включая ?, = (и другие) и пробел, кодируются с помощью =xx escape-последовательность.

Однако, когда я смотрю на какой SmtpClient производит, я обнаруживаю, что это не выходит из пробелов, что означает, что почтовый клиент получает этот заголовок:

Subject: =?iso-8859-1?Q?Votre enregistrement num=E9ro 123?=

означание, что кодирование повреждается относительно (мое чтение) RFC 2047. Некоторые почтовые клиенты совершенно довольны этим неправильным кодированием (большинство из них, на самом деле, включая Outlook и Gmail), но один (wanadoo.fr) отображает заголовок в его формате .raw. Это не то, что пользователь должен получить для наблюдения :-(

Там кто-либо - известное обходное решение для этой проблемы?

Примечание:.NET 4,0 реализации SmtpClient кодирует предмет как ожидалось, приводя к этому выводу, который корректен:

Subject: =?Windows-1252?Q?Votre_enregistrement_num=E9ro_123?=

5
задан Pierre Arnaud 11 April 2012 в 05:26
поделиться

1 ответ

Проблема в том, что отправитель SMTP использует универсальный кодировщик с возможностью печати в кавычках, который ничего не знает о специальном режиме для заголовков, поэтому я подозреваю, что простого обходного пути не будет.

Я бы проверил, есть ли какие-нибудь символы, отличные от ASCII, так что тема будет закодирована, и если да, то замените все пробелы символами подчеркивания (ASCII 95). Это должно работать, потому что символ подчеркивания должен интерпретироваться программой чтения почты как пробел, но не должен кодироваться наивным кодировщиком. Возможно, этот код будет работать:

string FixSubject(string subject)
{
    foreach (char ch in subject)
        if (ch > '\x007f')
            return subject.Replace(" ", "_");
    return subject;
}

Другая возможность - установить кодировку вашего электронного письма в Unicode или UTF-8, потому что это, кажется, запускает кодировку заголовков Base64 вместо цитируемой печати. Использование другого кодировщика должно полностью избежать ошибки.

3
ответ дан 15 December 2019 в 00:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: