web-dev-qa-db-fra.com

Envoi de mails C # avec des images en ligne avec SmtpClient

SmtpClient () vous permet d'ajouter des pièces jointes à vos mails, mais que se passe-t-il si vous voulez qu'une image apparaisse à l'ouverture du mail au lieu de la joindre?

Si je me souviens bien, cela peut être fait avec environ 4 lignes de code, mais je ne me souviens pas comment et je ne le trouve pas sur le site MSDN.

EDIT: Je n'utilise pas de site Web ou quoi que ce soit, pas même une adresse IP. Les images sont situées sur un disque dur. Une fois envoyés, ils devraient faire partie du courrier. Donc, je suppose que je pourrais utiliser une balise ... mais je ne suis pas trop sûr, car mon ordinateur ne diffuse pas.

37
KdgDev

Une solution souvent mentionnée consiste à ajouter une image en tant que Attachment au courrier, puis à la référencer dans le courrier HTML en utilisant une référence cid:

Toutefois, si vous utilisez plutôt la collection LinkedResources, les images en ligne apparaîtront toujours parfaitement, mais ne s'affichent pas en tant que pièces jointes supplémentaires dans le courrier. C'est ce que nous voulons arriver , alors c'est ce que je fais ici:

using (var client = new SmtpClient())
{
    MailMessage newMail = new MailMessage();
    newMail.To.Add(new MailAddress("[email protected]"));
    newMail.Subject = "Test Subject";
    newMail.IsBodyHtml = true;

    var inlineLogo = new LinkedResource(Server.MapPath("~/Path/To/YourImage.png"), "image/png");
    inlineLogo.ContentId = Guid.NewGuid().ToString();

    string body = string.Format(@"
            <p>Lorum Ipsum Blah Blah</p>
            <img src=""cid:{0}"" />
            <p>Lorum Ipsum Blah Blah</p>
        ", inlineLogo.ContentId);

    var view = AlternateView.CreateAlternateViewFromString(body, null, "text/html");
    view.LinkedResources.Add(inlineLogo);
    newMail.AlternateViews.Add(view);

    client.Send(newMail);
}

NOTE: Cette solution ajoute une AlternateView à votre MailMessage de type text/html. Pour être complet, vous devez également ajouter une AlternateView de type text/plain, contenant une version en texte brut de l’e-mail pour les clients de messagerie non HTML.

78
James McCormack

Le courrier électronique HTML et les images étant des pièces jointes, il vous suffit de faire référence à la ou aux images en fonction de leur ID de contenu, c.-à-d.

    Dim A As System.Net.Mail.Attachment = New System.Net.Mail.Attachment(txtImagePath.Text)
    Dim RGen As Random = New Random()
    A.ContentId = RGen.Next(100000, 9999999).ToString()
    EM.Body = "<img src='cid:" + A.ContentId +"'>" 

Il semble y avoir des exemples complets ici: Envoyer un courriel avec des images en ligne

13
Lazarus

Quand vous dites 4 lignes de code, vous parlez de this ?

System.Net.Mail.Attachment inline = new System.Net.Mail.Attachment(@"imagepath\filename.png");
inline.ContentDisposition.Inline = true;
12
Brandon

Qu'en est-il de la conversion des images en chaînes Base64? Autant que je sache, cela peut être facilement intégré au corps du courrier.

Jetez un oeil ici .

2
ccalboni

La solution déjà affichée est la meilleure que j'ai trouvée, je vais simplement la compléter avec par exemple si vous avez plusieurs images.

        string startupPath = AppDomain.CurrentDomain.RelativeSearchPath;
        string path = Path.Combine(startupPath, "HtmlTemplates", "NotifyTemplate.html");
        string body = File.ReadAllText(path);

        //General tags replacement.
        body = body.Replace("[NOMBRE_COMPLETO]", request.ToName);
        body = body.Replace("[ASUNTO_MENSAJE]", request.Subject);

        //Image List Used to replace into the template.
        string[] imagesList = { "h1.gif", "left.gif", "right.gif", "tw.gif", "fb.gif" };

        //Here we create link resources one for each image. 
        //Also the MIME type is obtained from the image name and not hardcoded.
        List<LinkedResource> imgResourceList = new List<LinkedResource>();
        foreach (var img in imagesList)
        {
            string imagePath = Path.Combine(startupPath, "Images", img);
            var image = new LinkedResource(imagePath, "image/" + img.Split('.')[1]);
            image.ContentId = Guid.NewGuid().ToString();
            image.ContentType.Name = img;
            imgResourceList.Add(image);
            body = body.Replace("{" + Array.IndexOf(imagesList, img) + "}", image.ContentId);
        }

        //Altern view for managing images and html text is created.
        var view = AlternateView.CreateAlternateViewFromString(body, null, "text/html");
        //You need to add one by one each link resource to the created view
        foreach (var imgResorce in imgResourceList)
        {
            view.LinkedResources.Add(imgResorce);
        }

        ThreadPool.QueueUserWorkItem(o =>
        {
            using (SmtpClient smtpClient = new SmtpClient(servidor, Puerto))
            {
                smtpClient.EnableSsl = true;
                smtpClient.DeliveryMethod = SmtpDeliveryMethod.Network;
                smtpClient.Timeout = 50000;
                smtpClient.UseDefaultCredentials = false;
                smtpClient.Credentials = new System.Net.NetworkCredential()
                {
                    UserName = UMail,
                    Password = password
                };
                using (MailMessage mailMessage = new MailMessage())
                {
                    mailMessage.IsBodyHtml = true;
                    mailMessage.From = new MailAddress(UMail);
                    mailMessage.To.Add(request.ToEmail);
                    mailMessage.Subject = "[NAPNYL] " + request.Subject;
                    mailMessage.AlternateViews.Add(view);
                    smtpClient.Send(mailMessage);
                }
            }
        });

Comme vous pouvez voir que vous avez un tableau de noms d’images, il est important que les images se trouvent dans le même dossier car il pointe vers le même dossier de sortie.

Enfin, le courrier électronique est envoyé en mode asynchrone afin que l'utilisateur n'ait pas à attendre qu'il soit envoyé.

0
Nelson Parra