Ariokh ([info]ariokh_dark) wrote,
@ 2007-06-05 12:47:00
Previous Entry  Add to memories!  Tell a Friend  Next Entry
Entry tags:it

Откопал шикарного усатого таракана в .Net Framework 2.0.
Столкнулись с проблемой нечитаемых почтовых уведомлений при использовании программного продукта, использующего .Net 2.0. Точнее несовпадения реальной и заявленной в хедере кодировки сообщения. По результатам исследования проблемы обнаружено, что проблема заключается в самой платформе .Net Framework 2.0.

При посылке сообщения в кодировке windows-1251 посредством System.Net.Mail.MailMessage и System.Net.Mail.SMTPClient в хедерах сообщения ставится koi8-r.


Копирую текст с небольшими изменениями прямо из письма в Мелкософт.

В MSDN от августа 2006 содержится следующая информация:

ms-help://MS.VSCC.v80/MS.MSDN.vAug06.en/cpref12/html/P_System_Text_Encoding_CodePage.htm

.NET Framework Class Library 
Encoding.CodePage Property

using System;
using System.Text;

public class SamplesEncoding  {

   public static void Main()  {

      // Print the header.
      Console.Write( "Name               " );
      Console.Write( "CodePage  " );
      Console.Write( "BodyName           " );
      Console.Write( "HeaderName         " );
      Console.Write( "WebName            " );
      Console.WriteLine( "Encoding.EncodingName" );

      // For every encoding, compare the name properties with EncodingInfo.Name.
      // Display only the encodings that have one or more different names.
      foreach( EncodingInfo ei in Encoding.GetEncodings() )  {
         Encoding e = ei.GetEncoding();

         if (( ei.Name != e.BodyName ) || ( ei.Name != e.HeaderName ) || ( ei.Name != e.WebName ))  {
            Console.Write( "{0,-18} ", ei.Name );
            Console.Write( "{0,-9} ",  e.CodePage );
            Console.Write( "{0,-18} ", e.BodyName );
            Console.Write( "{0,-18} ", e.HeaderName );
            Console.Write( "{0,-18} ", e.WebName );
            Console.WriteLine( "{0} ", e.EncodingName );
         }

      }

   }

}


/* 
This code produces the following output.

Name               CodePage  BodyName           HeaderName         WebName            Encoding.EncodingName
shift_jis          932       iso-2022-jp        iso-2022-jp        shift_jis          Japanese (Shift-JIS)
windows-1250       1250      iso-8859-2         windows-1250       windows-1250       Central European (Windows)
windows-1251       1251      koi8-r             windows-1251       windows-1251       Cyrillic (Windows)
Windows-1252       1252      iso-8859-1         Windows-1252       Windows-1252       Western European (Windows)
windows-1253       1253      iso-8859-7         windows-1253       windows-1253       Greek (Windows)
windows-1254       1254      iso-8859-9         windows-1254       windows-1254       Turkish (Windows)
csISO2022JP        50221     iso-2022-jp        iso-2022-jp        csISO2022JP        Japanese (JIS-Allow 1 byte Kana)
iso-2022-kr        50225     iso-2022-kr        euc-kr             iso-2022-kr        Korean (ISO)

*/


В результате этого становится невозможно при использовании классов System.Net.Mail.MailMessage и System.Net.Mail.SmtpClient стандартными средствами отправить корректное русскоязычное сообщение. В хедере content-type ставится кодировка koi8-r (кодовая страница 20866), в то время как используется windows-1251 (кодовая страница 1251) (информация о кодовых страницах - http://msdn2.microsoft.com/en-us/library/ms776446.aspx)

Следующий код демонстрирует проблему.

using System;
using System.Collections.Generic;
using System.Text;

using System.Net;
using SNM = System.Net.Mail;


namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            String sBody = Encoding.Default.EncodingName;
            SNM.MailMessage mm = new System.Net.Mail.MailMessage("login@domain.com", "login@domain.com", "Just a test message", "");

            SNM.SmtpClient sc = new System.Net.Mail.SmtpClient("email.corp.domain.com");

            mm.Body = mm.BodyEncoding.EncodingName + " " + mm.BodyEncoding.CodePage + " просто тестовое сообщение в Windows-1251";

            sc.Send(mm);

            mm.BodyEncoding = Encoding.Default;
            mm.Body = mm.BodyEncoding.EncodingName + " " + mm.BodyEncoding.CodePage + " просто тестовое сообщение в Windows-1251";

            sc.Send(mm);
                      
        }
    }
}


Для сообщения в кодировке Encoding.Default (установлена стандартная русская локаль) установлена koi8-r в хедере, несмотря на кодовую страницу 1251.

Текст сообщения: «Cyrillic (Windows) 1251 ОПНЯРН РЕЯРНБНЕ ЯННАЫЕМХЕ Б Windows-1251»
Заголовки: content-type: text/plain; charset=koi8-r

Соотв. при принудительном добавлении на почтовом сервере еще одного заголовка вида «content-type: text/plain; charset=windows-1251» до заголовка с koi8-r сообщение становится читаемым.

Текст сообщения: «Cyrillic (Windows) 1251 просто тестовое сообщение в Windows-1251»
Заголовки: Content-type:text/plain; charset=windows-1251
Received: …
subject: Just a test message
content-type: text/plain; charset=koi8-r



(4 comments) - (Post a new comment)


[info]ezoterik
2008-06-14 04:48 pm UTC (link)
Тоже возился с этим ( http://dev.ezoterik.info/otsylka-e-mail-cherez-c-sharp/ ). Похоже, что в более новых версиях фреймворка эта проблема все равно есть :-(
Вы случаем не нашли решения еще?

(Reply to this) (Thread)


[info]ariokh_dark
2008-06-14 07:24 pm UTC (link)
Какое там может быть решение? Честно написал в MS - оттуда ответ: у вас поддержка куплена? Если нет - идите нахуй.

Вот, собственно, и все.

(Reply to this) (Parent)


[info]dmitry_m
2009-12-17 07:22 pm UTC (link)
я этого таракана вчера поймал... только framework более новый, они там по-своему "выкрутились": всё, что не utf-8, стали перегонять в quoted-printable. т. е. сделали еще хуже. а для windows-1251 всё равно пишут koi8-r.

(Reply to this) (Thread)


[info]ariokh_dark
2009-12-17 10:27 pm UTC (link)
Ай молодцы!

(Reply to this) (Parent)


(4 comments) - (Post a new comment)

Create an Account
Forgot your login or password?
Login w/ OpenID
English • Español • Deutsch • Русский…