Wysyłanie wiadomości e-mail z załącznikami z C #, załączniki są dostarczane jako część 1.2 w Thunderbirdzie

113

Mam aplikację C #, która wysyła e-mailem raporty z arkuszy kalkulacyjnych programu Excel za pośrednictwem serwera Exchange 2007 przy użyciu protokołu SMTP. Są one w porządku dla użytkowników Outlooka, ale dla użytkowników Thunderbirda i Blackberry nazwy załączników zostały zmienione na „Część 1.2”.

Znalazłem ten artykuł, w którym opisano problem, ale nie wydaje mi się, aby go obejść. Nie mam kontroli nad serwerem Exchange, więc nie mogę tam wprowadzać zmian. Czy jest coś, co mogę zrobić po stronie C #? Próbowałem użyć krótkich nazw plików i kodowania HTML dla treści, ale żaden z nich nie zrobił różnicy.

Mój kod wysyłania poczty jest po prostu taki:

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);
}

Dzięki za wszelką pomoc.

Jon
źródło
Czy próbowałeś zdefiniować / zmienić Attachment.Namewłaściwość?
Alex
Nie, nie mam - „Pobiera lub ustawia wartość nazwy typu zawartości MIME”, czy masz sugestię, jaką wartość wypróbować? Dzięki.
Jon
Ikona Namejest wyświetlana jako nazwa załącznika po odebraniu wiadomości e-mail z załącznikiem. Możesz więc spróbować dowolnej wartości.
Alex

Odpowiedzi:

115

Prosty kod do wysłania wiadomości e-mail z załącznikiem.

źródło: 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);

}
Ranadheer Reddy
źródło
21
Powinieneś opakować MailMessage i SmtpClient instrukcjami using, aby upewnić się, że są one poprawnie usunięte
Andrew
1
@Andrew - jak mam to zrobić?
Steam
Wypróbowałem ten kod i otrzymałem błąd pokazany w tym poście - stackoverflow.com/questions/20845469/ ...
Steam
1
@Steam, możesz to zrobićusing(SmtpClient SmtpServer = new SmtpClient("smtp.gmail.com")) { //code goes here using(MailMessage mail = new MailMessage()){ //code goes here } }
Shamseer K
92

Jawne wypełnienie pól ContentDisposition załatwiło sprawę.

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);                
}

BTW , w przypadku Gmaila możesz mieć pewne wyjątki dotyczące bezpieczeństwa SSL, a nawet portu!

smtpClient.EnableSsl = true;
smtpClient.Port = 587;
Jon
źródło
2
Dlaczego by nie skorzystać z FileInfoobiektu dostać CreationTime, LastWriteTimei LastAccessTimewłaściwości? I tak tworzysz, aby uzyskać tę Lengthwłaściwość.
sampathsris
1
Nie zapomnij załącznika.Dispose () lub ten plik pozostanie zablokowany i nie będziesz mógł zapisywać w nim danych.
Pau Dominguez
7

Oto prosty kod do wysyłania poczty z załącznikiem

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);  
}

Czytaj więcej Wysyłanie e-maili z załącznikiem w C #

Pankaj Prakash
źródło
4

Ukończenie rozwiązania Ranadheer przy użyciu Server.MapPath do zlokalizowania pliku

System.Net.Mail.Attachment attachment;
attachment = New System.Net.Mail.Attachment(Server.MapPath("~/App_Data/hello.pdf"));
mail.Attachments.Add(attachment);
Nuno Ribeiro
źródło
Skąd się Server.MapPathbierze i kiedy należy go używać?
Kimmax,
1
private void btnSent_Click(object sender, EventArgs e)
{
    try
    {
        MailMessage mail = new MailMessage();
        SmtpClient SmtpServer = new SmtpClient("smtp.gmail.com");

        mail.From = new MailAddress(txtAcc.Text);
        mail.To.Add(txtToAdd.Text);
        mail.Subject = txtSub.Text;
        mail.Body = txtContent.Text;
        System.Net.Mail.Attachment attachment;
        attachment = new System.Net.Mail.Attachment(txtAttachment.Text);
        mail.Attachments.Add(attachment);

        SmtpServer.Port = 587;
        SmtpServer.Credentials = new System.Net.NetworkCredential(txtAcc.Text, txtPassword.Text);

        SmtpServer.EnableSsl = true;

        SmtpServer.Send(mail);
        MessageBox.Show("mail send");
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.ToString());
    }
}

private void button1_Click(object sender, EventArgs e)
{
    MailMessage mail = new MailMessage();
    openFileDialog1.ShowDialog();
    System.Net.Mail.Attachment attachment;
    attachment = new System.Net.Mail.Attachment(openFileDialog1.FileName);
    mail.Attachments.Add(attachment);
    txtAttachment.Text =Convert.ToString (openFileDialog1.FileName);
}
Khang Pham
źródło
1

Zrobiłem krótki kod, aby to zrobić i chcę się z tobą podzielić.

Tutaj główny kod:

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);
  }

}

W swoim przycisku rób takie rzeczy
, możesz dodawać pliki jpg lub pdf i nie tylko ... to tylko przykład

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);

}
}
elaz
źródło
0

Spróbuj tego:

private void btnAtt_Click(object sender, EventArgs e) {

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

    MyMsg.Attachments.Add(myFile);


}
Ashar Kashif
źródło
0

Wypróbowałem kod dostarczony przez Ranadheer Reddy (powyżej) i działał świetnie. Jeśli korzystasz z komputera firmowego z ograniczonym serwerem, może być konieczna zmiana portu SMTP na 25 i pozostawienie nazwy użytkownika i hasła pustych, ponieważ zostaną one automatycznie wypełnione przez administratora.

Początkowo próbowałem użyć EASendMail z nugent menedżera pakietów, ale zdałem sobie sprawę, że jest to płatna wersja z 30-dniową wersją próbną. Nie trać czasu, chyba że planujesz go kupić. Zauważyłem, że program działał znacznie szybciej przy użyciu EASendMail, ale dla mnie darmowy był szybszy.

Tylko moje 2 centy warte.

Aubrey Love
źródło
0

Użyj tej metody, aby w ramach usługi poczty e-mail można było dołączyć dowolną treść wiadomości e-mail i załączniki do programu Microsoft Outlook

using Outlook = Microsoft.Office.Interop.Outlook; // Odwołanie do Microsoft.Office.Interop.Outlook z lokalnego lub nuget, jeśli później będziesz używać agenta kompilacji

 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."
                    };
                }
Vuminkosi Vincent Matibe
źródło