System.Net.Mail и =? Utf-8?B?XXXXX.... Заголовки
Я пытаюсь использовать приведенный ниже код для отправки сообщений через System.Net.Mail
и иногда получаю такие предметы, как '=?utf-8?B?W3AxM25dIEZpbGV...'
(Обрезается). Это код, который называется:
MailMessage message = new MailMessage()
{
From = new MailAddress("someone@somewhere.com", "Service"),
BodyEncoding = Encoding.UTF8,
Body = body,
IsBodyHtml = true,
ReplyTo = new MailAddress("do.not.reply@somewhere.com"),
SubjectEncoding = Encoding.UTF8
};
foreach (string emailAddress in addresses)
{
message.To.Add(new MailAddress(emailAddress.Trim(), "Person"));
}
message.Subject = subject;
Я хотел бы подчеркнуть, что это не происходит все время.
Что я делаю неправильно?
3 ответа
Если ваша тема содержит символы вне диапазона ASCII, тогда почтовое программное обеспечение должно их кодировать (почта RFC2822 не допускает символы не ASCII в заголовках). Есть два способа сделать это:
- Цитируется для печати (тема начинается с
"=?utf-8?Q"
) - Base64 (тема начинается с
"=?utf-8?B"
)
Похоже, что фреймворк решил, что кодировка Base64 более эффективна (= короче), чем кодировка для печати в кавычках. Это имеет смысл, когда ваш предмет содержит относительно много символов вне диапазона ASCII.
Чтобы ответить на ваш вопрос: вы ничего не делаете неправильно. Вот так должна выглядеть интернет-почта с не-ASCII символами. Конечно, программное обеспечение, которое читает такую почту, должно обнаруживать и декодировать такие предметные поля.
Я наткнулся на этот пост, когда отлаживал идентичную проблему, и на основании моих дальнейших исследований я могу дать альтернативное объяснение Андреасу:
Проблема может заключаться в том, что программное обеспечение вашего почтового клиента (в моем случае Outlook 2003) неправильно декодирует строку темы. Другими словами, это ошибка в Outlook, а не в.NET или вашей программе.
Если вы используете значение темы, подобное этому (буква "с" повторяется 256 раз), оно отлично отображается в Outlook:
subject = New String("c"c, 256)
Аналогичным образом, если вы используете тему, подобную этой (буква "с" повторяется 178 раз, с добавленным символом неразрывного пробела в Юникоде), она также отображается в Outlook так, как ожидается:
subject = New String("c"c, 178) + System.Text.Encoding.UTF8.GetChars(New Byte() {194, 160})
Однако следующая тема отображается в Outlook как "=? Utf-8?B":
subject = New String("c"c, 179) + System.Text.Encoding.UTF8.GetChars(New Byte() {194, 160})
Разница в том, что эта третья строка темы имеет 256 байт при кодировке UTF-8. Я предполагаю, что Outlook должен обрезать строку темы до 255 символов перед ее отображением... что было бы хорошо, за исключением того, что он делает это, обрезая закодированную строку до 255 байтов, что обрезает терминатор кодирования ("?="), что делает его некодируемым.
Это ошибка в Outlook, а не в вашем почтовом провайдере или.NET; Вы можете увидеть полную, не усеченную строку темы в кодировке UTF-8 в Outlook, щелкнув правой кнопкой мыши сообщение в списке сообщений и выбрав "Параметры..." в контекстном меню, а затем прокручивая вниз в поле "Заголовки Интернета" до Вы видите строку, начинающуюся с "Subject:".
Вопреки ситуации, которую предлагает Андреас, проблема проявляется не только в том случае, когда имеется много символов, не входящих в ASCII, но и в том случае, когда имеется один или несколько символов, отличных от ASCII, и строка темы является длинной. Обходной путь может заключаться в том, чтобы использовать более короткую строку темы или удалить все символы не-ASCII в вашей теме.
(Эта ошибка была особенно сложной для меня, чтобы отследить, потому что, как и выше, проблемные данные не содержали очевидных не-ASCII-символов - только несколько неразрывных пробелов. Они отображают то же, что и обычные ASCII-пробелы, когда вы распечатываете их в консоль. Более того, если вы измените значение строковой переменной в отладчике Visual Studio, он автоматически заменит их обычными пробелами.)
Ответ может быть в остальной части обрезанной темы - предоставленный вами раздел декодируется как "Файл [p13n]", но если у вас есть какие-либо не-ASCII-символы, то я бы ожидал, что он будет кодироваться так, как он имеет
Хотя я не уверен, возможно, эта статья о MIME в Википедии может помочь получить дополнительную справочную информацию.
Я нашел быстрое решение на форумах Microsoft: http://social.msdn.microsoft.com/Forums/en-US/netfxnetcom/thread/67414337-19a6-4128-b1a0-212404cc2cb1/
с помощью класса, предоставленного по этой ссылке: http://social.msdn.microsoft.com/Forums/en-US/dotnetframeworkde/thread/b6c764f7-4697-4394-b45f-128a24306d55