SmtpClient (.NET) не кодирует почтовый заголовок в соответствии с RFC 2047 - PullRequest
5 голосов
/ 15 марта 2010

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

Subject: Votre enregistrement numéro 123

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

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

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

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

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

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

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

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

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

Ответы [ 2 ]

3 голосов
/ 16 марта 2010

Проблема заключается в том, что отправитель 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 вместо цитируемой для печати. Использование другого кодировщика должно полностью исключить ошибку.

1 голос
/ 11 апреля 2012

Это было исправлено в реализации NET 4.0 SmtpClient. Он кодирует субъект, как и ожидалось, получая этот вывод, который является правильным:

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...