Этот кусок кода показывает, как можно программно отослать электронное письмо средствами C#. Письмо отсылается через указанный SMTP-сервер, который требует авторизацию. Так же к письму можно прикрепить одно или несколько вложений.
//Адрес SMTP-сервера String smtpHost = "SMTP.SERVER.RU"; //Порт SMTP-сервера int smtpPort = 25; //Логин String smtpUserName = "LOGIN"; //Пароль String smtpUserPass = "PASSWORD"; //Создание подключения SmtpClient client = new SmtpClient(smtpHost, smtpPort); client.Credentials = new NetworkCredential(smtpUserName, smtpUserPass); //Адрес для поля "От" String msgFrom = "LOGIN@SERVER.RU"; //Адрес для поля "Кому" (адрес получателя) String msgTo = "KUDA@TO.RU"; //Тема письма String msgSubject = "Письмо от C#"; //Текст письма String msgBody = "Привет!\r\n\r\nЭто тестовое письмо\r\n\r\n--\r\nС уважением, C# :-)"; //Вложение для письма //Если нужно больше вложений, для каждого вложения создаем свой объект Attachment с нужным путем к файлу Attachment attachData = new Attachment("D:\Тестовое вложение.zip"); //Создание сообщения MailMessage message = new MailMessage(msgFrom, msgTo, msgSubject, msgBody); //Крепим к сообщению подготовленное заранее вложение message.Attachments.Add(attachData); try { //Отсылаем сообщение client.Send(message); } catch (SmtpException ex) { //В случае ошибки при отсылке сообщения можем увидеть, в чем проблема Console.WriteLine(ex.InnerException.Message.ToString()); }
Тело письма и его заголовок будут созданы и отосланы в кодировке — UTF-8. Если же захочется отослать письмо в кодировке windows-1251, то начинаются проблемы. Мне удалось найти только одно достаточно подробное описание этой проблемы. И в более свежих версиях фреймворка (помимо .Net Framework 2.0) точно такая же проблема.
Да, отчасти помогает прописывание вручную заголовка, говорящего о кодировке всего письма, но с другой стороны, не так уж все радужно. Итак, перед кодом отсылки сообщения (после 29-ой строки) добавляем следующий код:
message.SubjectEncoding = Encoding.Default; message.BodyEncoding = Encoding.Default; message.Headers["Content-type"] = "text/plain; charset=windows-1251";
В итоге мы имеем письмо, у которого два раза (второй раз вставляется автоматом) повторяется заголовок Content-type, в первом указана кодировка windows-1251, а во втором настырный .Net вставляет UTF-8. Не думаю, что такое дублирование заголовков можно назвать корректным. Но это, похоже, единственный способ добиться какой-то адекватности отображения тела письма в почтовой программе, которая получит его.
Для просмотра писем я использую Mozilla Thunderbird. В нем тело письма отображается нормально, но при этом он не понимает кодировки заголовка письма и отображает его некорректно. Если оставить заголовок в кодировке UTF-8, а тело письма создавать в windows-1251:
message.BodyEncoding = Encoding.Default; message.Headers["Content-type"] = "text/plain; charset=windows-1251";
Тогда Thunderbird правильно отображает письмо. Но все эти ухищрения достаточно сомнительны из-за того, что каждый почтовый клиент может по-своему трактовать двойной и противоречивый заголовок Content-type. Так, к примеру, если посмотреть на такое письмо через вэбовский клиент mail.ru, то при любых раскладах тело письма отображается коряво. Тема же отображается правильно, только если отсылать ее в UTF-8.
Глядя на эту печальную картину, в голову приходит только два варианта решения проблемы. Плюнуть и отсылать письма в UTF-8 или же самостоятельно подключаться к SMTP-серверу и «вручную общаться» с ним по протоколу SMTP, а не использовать готовую реализацию в виде класса SmtpClient.