Этот кусок кода показывает, как можно программно отослать электронное письмо средствами 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.