Envoi d'e-mails avec des pièces jointes à partir de C #, les pièces jointes arrivent en tant que partie 1.2 dans Thunderbird


113

J'ai une application C # qui envoie par e-mail des rapports de feuille de calcul Excel via un serveur Exchange 2007 utilisant SMTP. Celles-ci arrivent bien pour les utilisateurs d'Outlook, mais pour les utilisateurs de Thunderbird et Blackberry, les pièces jointes ont été renommées «Partie 1.2».

J'ai trouvé cet article qui décrit le problème, mais ne semble pas me donner une solution de contournement. Je n'ai pas le contrôle du serveur Exchange, je ne peux donc pas y apporter de modifications. Puis-je faire quelque chose du côté C #? J'ai essayé d'utiliser des noms de fichiers courts et un codage HTML pour le corps, mais aucun des deux n'a fait de différence.

Mon code d'envoi de courrier est simplement le suivant:

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

Merci pour toute aide.


Avez-vous essayé de définir / modifier la Attachment.Namepropriété?
Alex

Non, je n'ai pas - "Obtient ou définit la valeur du nom du type de contenu MIME", avez-vous une suggestion quant à la valeur à essayer? Merci.
Jon

Le Names'affiche comme nom de la pièce jointe lorsque l'e-mail avec la pièce jointe est reçu. Vous pouvez donc essayer n'importe quelle valeur.
Alex

Réponses:


115

Code simple pour envoyer un e-mail avec pièce jointe.

source: 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
Vous devez encapsuler MailMessage et SmtpClient avec des instructions using pour vous assurer qu'elles sont supprimées correctement
Andrew

1
@Andrew - comment puis-je faire ça?
Steam

J'ai essayé ce code et j'ai eu l'erreur indiquée dans cet article - stackoverflow.com/questions/20845469/…
Steam

1
@Steam, vous pouvez faire comme çausing(SmtpClient SmtpServer = new SmtpClient("smtp.gmail.com")) { //code goes here using(MailMessage mail = new MailMessage()){ //code goes here } }
Shamseer K

92

Le remplissage explicite des champs ContentDisposition a fait l'affaire.

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 , dans le cas de Gmail, vous pouvez avoir quelques exceptions sur SSL sécurisé ou même le port!

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

2
Pourquoi ne pas utiliser un FileInfoobjet pour obtenir CreationTime, LastWriteTime, et LastAccessTimepropriétés? Vous en créez un pour obtenir la Lengthpropriété de toute façon.
sampathsris

1
N'oubliez pas la pièce jointe.Dispose () ou ce fichier reste verrouillé et vous ne pourrez pas y écrire de données.
Pau Dominguez

7

Voici un simple code d'envoi de mail avec pièce jointe

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

En savoir plus Envoi d'e-mails avec pièce jointe en C #


4

Terminer la solution de Ranadheer, en utilisant Server.MapPath pour localiser le fichier

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

D'où Server.MapPathvient-il et quand doit-il être utilisé?
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

J'ai créé un code court pour le faire et je souhaite le partager avec vous.

Voici le code principal:

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

}

Dans votre bouton, faites des choses comme ça,
vous pouvez ajouter vos fichiers jpg ou pdf et plus encore .. ce n'est qu'un exemple

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

Essaye ça:

private void btnAtt_Click(object sender, EventArgs e) {

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

    MyMsg.Attachments.Add(myFile);


}

0

J'ai essayé le code fourni par Ranadheer Reddy (ci-dessus) et cela a très bien fonctionné. Si vous utilisez un ordinateur d'entreprise doté d'un serveur restreint, vous devrez peut-être changer le port SMTP sur 25 et laisser votre nom d'utilisateur et votre mot de passe vides car ils seront automatiquement remplis par votre administrateur.

À l'origine, j'ai essayé d'utiliser EASendMail à partir du gestionnaire de paquets nugent, pour me rendre compte qu'il s'agit d'une version payante avec un essai de 30 jours. Ne perdez pas votre temps avec elle à moins que vous ne prévoyiez de l'acheter. J'ai remarqué que le programme fonctionnait beaucoup plus rapidement en utilisant EASendMail, mais pour moi, la gratuité l'emportait rapidement.

Juste mes 2 cents.


0

Utilisez cette méthode sous votre service de messagerie, il peut attacher n'importe quel corps d'e-mail et pièces jointes à Microsoft Outlook

en utilisant Outlook = Microsoft.Office.Interop.Outlook; // Référence Microsoft.Office.Interop.Outlook depuis local ou nuget si vous utiliserez un agent de build plus tard

 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."
                    };
                }
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.