Inviando e-mail con allegati da C #, gli allegati arrivano come parte 1.2 in Thunderbird


113

Ho un'applicazione C # che invia tramite posta elettronica i rapporti del foglio di calcolo Excel tramite un server Exchange 2007 utilizzando SMTP. Questi arrivano bene per gli utenti di Outlook, ma per gli utenti di Thunderbird e Blackberry gli allegati sono stati rinominati come "Parte 1.2".

Ho trovato questo articolo che descrive il problema, ma non sembra fornirmi una soluzione alternativa. Non ho il controllo del server Exchange, quindi non posso apportare modifiche lì. C'è qualcosa che posso fare in C #? Ho provato a utilizzare nomi di file brevi e codifica HTML per il corpo, ma nessuno dei due ha fatto la differenza.

Il mio codice di invio della posta è semplicemente questo:

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

Grazie per qualsiasi aiuto.


Hai provato a definire / cambiare Attachment.Nameproprietà?
Alex

No, non ho - "Ottiene o imposta il valore del nome del tipo di contenuto MIME", hai un suggerimento su quale valore provare? Grazie.
Jon

Il Nameviene visualizzato come nome del allegato quando viene ricevuto l'e-mail con l'allegato. Quindi puoi provare qualsiasi valore.
Alex

Risposte:


115

Codice semplice per inviare e-mail con allegato.

fonte: 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 mail@gmail.com");
    mail.To.Add("to_mail@gmail.com");
    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 mail@gmail.com", "your password");
    SmtpServer.EnableSsl = true;

    SmtpServer.Send(mail);

}

21
Dovresti racchiudere MailMessage e SmtpClient con le istruzioni using per assicurarti che siano smaltite correttamente
Andrew

1
@Andrew - come posso farlo?
Steam il

Ho provato questo codice e ho ricevuto l'errore mostrato in questo post - stackoverflow.com/questions/20845469/…
Steam

1
@Steam puoi fare cosìusing(SmtpClient SmtpServer = new SmtpClient("smtp.gmail.com")) { //code goes here using(MailMessage mail = new MailMessage()){ //code goes here } }
Shamseer K

92

La compilazione esplicita dei campi ContentDisposition ha funzionato.

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

A proposito , nel caso di Gmail, potresti avere alcune eccezioni sulla sicurezza SSL o addirittura sulla porta!

smtpClient.EnableSsl = true;
smtpClient.Port = 587;

2
Perché non si utilizzare un FileInfooggetto per ottenere CreationTime, LastWriteTime, e LastAccessTimele proprietà? Ne stai creando uno comunque per ottenere la Lengthproprietà.
sampathsris

1
Non dimenticare l'allegato.Dispose () o questo file rimane bloccato e non potrai scrivere dati su di esso.
Pau Dominguez

7

Ecco un semplice codice di invio di posta con allegato

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

    mailServer.Credentials = new System.Net.NetworkCredential("myemail@gmail.com", "mypassword");  

    string from = "myemail@gmail.com";  
    string to = "reciever@gmail.com";  
    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);  
}

Ulteriori informazioni Invio di e-mail con allegato in C #


4

Completando la soluzione di Ranadheer, utilizzando Server.MapPath per individuare il file

System.Net.Mail.Attachment attachment;
attachment = New System.Net.Mail.Attachment(Server.MapPath("~/App_Data/hello.pdf"));
mail.Attachments.Add(attachment);

Da dove Server.MapPathviene e quando dovrebbe essere utilizzato?
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);
}

1

Ho creato un breve codice per farlo e voglio condividerlo con te.

Qui il codice principale:

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

}

Nel tuo pulsante fai cose come questa
puoi aggiungere i tuoi file jpg o pdf e altro ... questo è solo un esempio

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

}
}

0

Prova questo:

private void btnAtt_Click(object sender, EventArgs e) {

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

    MyMsg.Attachments.Add(myFile);


}

0

Ho provato il codice fornito da Ranadheer Reddy (sopra) e ha funzionato benissimo. Se stai utilizzando un computer aziendale con un server limitato, potresti dover cambiare la porta SMTP in 25 e lasciare il nome utente e la password vuoti poiché verranno compilati automaticamente dall'amministratore.

Inizialmente, ho provato a utilizzare EASendMail dal gestore di pacchetti nugent, solo per rendermi conto che è una versione a pagamento con 30 giorni di prova. Non sprecare il tuo tempo con esso a meno che tu non abbia intenzione di acquistarlo. Ho notato che il programma è stato eseguito molto più velocemente utilizzando EASendMail, ma per me, gratuito ha superato velocemente.

Solo i miei 2 centesimi di valore.


0

Usa questo metodo con il tuo servizio di posta elettronica che può allegare qualsiasi corpo e allegato di posta elettronica a Microsoft Outlook

utilizzando Outlook = Microsoft.Office.Interop.Outlook; // Fare riferimento a Microsoft.Office.Interop.Outlook da local o nuget se si utilizzerà un agente di compilazione in un secondo momento

 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 = "con@def.com";//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."
                    };
                }
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.