Отправка электронной почты с вложениями из C #, вложения поступают как часть 1.2 в Thunderbird

У меня есть приложение C #, которое отправляет электронные таблицы Excel через сервер Exchange 2007 с использованием SMTP. Они подходят для пользователей Outlook, но для пользователей Thunderbird и Blackberry вложения были переименованы в «Часть 1.2».

Я нашел эту статью, в которой описывается проблема, но, похоже, дайте мне обходной путь. У меня нет контроля над сервером Exchange, поэтому я не могу вносить там изменения. Могу ли я что-нибудь сделать на конце C #? Я пробовал использовать короткие имена файлов и кодировку HTML для тела, но ничего не изменилось.

Мой код отправки почты такой:

public static void SendMail(string recipient, string subject, string body, string attachmentFilename)
{
    SmtpClient smtpClient = new SmtpClient();
    NetworkCredential basicCredential = new NetworkCredential(MailConst.Username, MailConst.Password);
    MailMessage message = new MailMessage();
    MailAddress fromAddress = new MailAddress(MailConst.Username);

    // setup up the host, increase the timeout to 5 minutes
    smtpClient.Host = MailConst.SmtpServer;
    smtpClient.UseDefaultCredentials = false;
    smtpClient.Credentials = basicCredential;
    smtpClient.Timeout = (60 * 5 * 1000);

    message.From = fromAddress;
    message.Subject = subject;
    message.IsBodyHtml = false;
    message.Body = body;
    message.To.Add(recipient);

    if (attachmentFilename != null)
        message.Attachments.Add(new Attachment(attachmentFilename));

    smtpClient.Send(message);
}

Спасибо за любую помощь.


person Jon    schedule 13.05.2010    source источник
comment
Вы пытались определить / изменить свойство Attachment.Name?   -  person Alex    schedule 13.05.2010
comment
Нет, у меня нет - Получает или задает значение имени типа содержимого MIME. Есть ли у вас предложения относительно того, какое значение попробовать? Спасибо.   -  person Jon    schedule 13.05.2010
comment
Name отображается как имя вложения, когда получено электронное письмо с вложением. Так что вы можете попробовать любое значение.   -  person Alex    schedule 13.05.2010


Ответы (8)


Простой код для отправки электронного письма с вложением.

источник: http://www.coding-issues.com/2012/11/sending-email-with-attachments-from-c.html

using System.Net;
using System.Net.Mail;

public void email_send()
{
    MailMessage mail = new MailMessage();
    SmtpClient SmtpServer = new SmtpClient("smtp.gmail.com");
    mail.From = new MailAddress("your [email protected]");
    mail.To.Add("[email protected]");
    mail.Subject = "Test Mail - 1";
    mail.Body = "mail with attachment";

    System.Net.Mail.Attachment attachment;
    attachment = new System.Net.Mail.Attachment("c:/textfile.txt");
    mail.Attachments.Add(attachment);

    SmtpServer.Port = 587;
    SmtpServer.Credentials = new System.Net.NetworkCredential("your [email protected]", "your password");
    SmtpServer.EnableSsl = true;

    SmtpServer.Send(mail);

}
person Ranadheer Reddy    schedule 28.05.2012
comment
Вы должны заключить MailMessage и SmtpClient с помощью операторов using, чтобы убедиться, что они размещены правильно. - person Andrew; 14.01.2013
comment
@ Андрей, как мне это сделать? - person Steam; 30.12.2013
comment
Я попробовал этот код и получил ошибку, показанную в этом сообщении - stackoverflow.com/questions/20845469/ - person Steam; 30.12.2013
comment
@Steam, ты можешь сделать это using(SmtpClient SmtpServer = new SmtpClient("smtp.gmail.com")) { //code goes here using(MailMessage mail = new MailMessage()){ //code goes here } } - person Shamseer K; 01.02.2017

Явное заполнение полей ContentDisposition помогло.

if (attachmentFilename != null)
{
    Attachment attachment = new Attachment(attachmentFilename, MediaTypeNames.Application.Octet);
    ContentDisposition disposition = attachment.ContentDisposition;
    disposition.CreationDate = File.GetCreationTime(attachmentFilename);
    disposition.ModificationDate = File.GetLastWriteTime(attachmentFilename);
    disposition.ReadDate = File.GetLastAccessTime(attachmentFilename);
    disposition.FileName = Path.GetFileName(attachmentFilename);
    disposition.Size = new FileInfo(attachmentFilename).Length;
    disposition.DispositionType = DispositionTypeNames.Attachment;
    message.Attachments.Add(attachment);                
}

Кстати, в случае с Gmail у вас могут быть некоторые исключения, касающиеся безопасности ssl или даже порта!

smtpClient.EnableSsl = true;
smtpClient.Port = 587;
person Jon    schedule 13.05.2010
comment
Почему бы вам не использовать объект FileInfo для получения свойств CreationTime, LastWriteTime и LastAccessTime? Вы все равно создаете его, чтобы получить свойство Length. - person sampathsris; 17.12.2015
comment
Не забывайте вложение. Dispose (), иначе этот файл останется заблокированным, и вы не сможете записывать в него данные. - person Pau Dominguez; 12.11.2019

Вот простой код отправки почты с вложением

try  
{  
    SmtpClient mailServer = new SmtpClient("smtp.gmail.com", 587);  
    mailServer.EnableSsl = true;  

    mailServer.Credentials = new System.Net.NetworkCredential("[email protected]", "mypassword");  

    string from = "[email protected]";  
    string to = "[email protected]";  
    MailMessage msg = new MailMessage(from, to);  
    msg.Subject = "Enter the subject here";  
    msg.Body = "The message goes here.";
    msg.Attachments.Add(new Attachment("D:\\myfile.txt"));
    mailServer.Send(msg);  
}  
catch (Exception ex)  
{  
    Console.WriteLine("Unable to send email. Error : " + ex);  
}

Подробнее Отправка сообщений электронной почты с вложением в C #

person Pankaj Prakash    schedule 15.05.2015

Завершение решения Ранадира, используя Server.MapPath для поиска файла

System.Net.Mail.Attachment attachment;
attachment = New System.Net.Mail.Attachment(Server.MapPath("~/App_Data/hello.pdf"));
mail.Attachments.Add(attachment);
person Nuno Ribeiro    schedule 21.05.2014
comment
Откуда Server.MapPath и когда его использовать? - person Kimmax; 05.07.2016
comment
Человек, писавший, вероятно, был программистом ASP.NET, и я думаю, что это просто помогает дать полное квалифицированное имя файла из относительного имени файла. Исходный вопрос не упоминал ASP.NET; вы можете просто поместить туда полную ссылку на имя файла. - person NealWalters; 17.12.2020

Я сделал для этого короткий код и хочу поделиться им с вами.

Вот основной код:

public void Send(string from, string password, string to, string Message, string subject, string host, int port, string file)
{

  MailMessage email = new MailMessage();
  email.From = new MailAddress(from);
  email.To.Add(to);
  email.Subject = subject;
  email.Body = Message;
  SmtpClient smtp = new SmtpClient(host, port);
  smtp.UseDefaultCredentials = false;
  NetworkCredential nc = new NetworkCredential(from, password);
  smtp.Credentials = nc;
  smtp.EnableSsl = true;
  email.IsBodyHtml = true;
  email.Priority = MailPriority.Normal;
  email.BodyEncoding = Encoding.UTF8;

  if (file.Length > 0)
  {
    Attachment attachment;
    attachment = new Attachment(file);
    email.Attachments.Add(attachment);
  }

  // smtp.Send(email);
  smtp.SendCompleted += new SendCompletedEventHandler(SendCompletedCallBack);
  string userstate = "sending ...";
  smtp.SendAsync(email, userstate);
}

private static void SendCompletedCallBack(object sender,AsyncCompletedEventArgs e) {
  string result = "";
  if (e.Cancelled)
  {    
    MessageBox.Show(string.Format("{0} send canceled.", e.UserState),"Message",MessageBoxButtons.OK,MessageBoxIcon.Information);
  }
  else if (e.Error != null)
  {
    MessageBox.Show(string.Format("{0} {1}", e.UserState, e.Error), "Message", MessageBoxButtons.OK, MessageBoxIcon.Information);
  }
  else {
    MessageBox.Show("your message is sended", "Message", MessageBoxButtons.OK, MessageBoxIcon.Information);
  }

}

На кнопке делайте что-то подобное
вы можете добавлять свои файлы jpg или pdf и многое другое .. это всего лишь пример

using (OpenFileDialog attachement = new OpenFileDialog()
{
  Filter = "Exel Client|*.png",
  ValidateNames = true
})
{
if (attachement.ShowDialog() == DialogResult.OK)
{
  Send("[email protected]", "gmail_password", 
       "[email protected]", "just smile ", "mail with attachement",
       "smtp.gmail.com", 587, attachement.FileName);

}
}
person elaz    schedule 13.12.2016

Попробуй это:

private void btnAtt_Click(object sender, EventArgs e) {

    openFileDialog1.ShowDialog();
    Attachment myFile = new Attachment(openFileDialog1.FileName);

    MyMsg.Attachments.Add(myFile);


}
person Ashar Kashif    schedule 29.12.2014

Я попробовал код, предоставленный Ранадиром Редди (см. Выше), и он отлично сработал. Если вы используете корпоративный компьютер с ограниченным сервером, вам может потребоваться изменить порт SMTP на 25 и оставить пустые имя пользователя и пароль, так как они будут автоматически заполнены администратором.

Первоначально я пробовал использовать EASendMail из диспетчера пакетов nugent, только чтобы понять, что это платная версия с 30-дневной пробной версией. Не тратьте на это время, если не планируете покупать его. Я заметил, что при использовании EASendMail программа работала намного быстрее, но для меня бесплатная игра важнее скорости.

Только мои 2 цента стоят.

person Aubrey Love    schedule 27.04.2018

Используйте этот метод в своей почтовой службе, он может прикреплять любое тело электронной почты и вложения к Microsoft Outlook.

используя Outlook = Microsoft.Office.Interop.Outlook; // Ссылка на Microsoft.Office.Interop.Outlook с локального компьютера или nuget, если вы будете использовать агент сборки позже

 try {
                    var officeType = Type.GetTypeFromProgID("Outlook.Application");
    
                    if(officeType == null) {//outlook is not installed
                        return new PdfErrorResponse {
                            ErrorMessage = "System cant start Outlook!, make sure outlook is installed on your computer."
                        };
                    } else {
                        // Outlook is installed.    
                        // Continue your work.
                        Outlook.Application objApp = new Outlook.Application();
                        Outlook.MailItem mail = null;
                        mail = (Outlook.MailItem)objApp.CreateItem(Outlook.OlItemType.olMailItem);
                        //The CreateItem method returns an object which has to be typecast to MailItem 
                        //before using it.
                        mail.Attachments.Add(attachmentFilePath,Outlook.OlAttachmentType.olEmbeddeditem,1,$"Attachment{ordernumber}");
                        //The parameters are explained below
                        mail.To = recipientEmailAddress;
                        //mail.CC = "[email protected]";//All the mail lists have to be separated by the ';'
    
                        //To send email:
                        //mail.Send();
                        //To show email window
                        await Task.Run(() => mail.Display());
                    }
    
                } catch(System.Exception) {
                    return new PdfErrorResponse {
                        ErrorMessage = "System cant start Outlook!, make sure outlook is installed on your computer."
                    };
                }
person Vuminkosi Vincent Matibe    schedule 10.08.2020