Enviar imagen en línea por correo electrónico


105

Tener problemas para enviar una imagen por correo electrónico como una imagen incrustada en el cuerpo. El archivo de imagen se muestra como un archivo adjunto que está bien, pero la parte de la imagen en línea solo se muestra como una x roja.

Esto es lo que tengo hasta ahora

LinkedResource inline = new LinkedResource(filePath);
inline.ContentId = Guid.NewGuid().ToString();
MailMessage mail = new MailMessage();
Attachment att = new Attachment(filePath);
att.ContentDisposition.Inline = true;
mail.From = from_email;
mail.To.Add(data.email);
mail.Subject = "Client: " + data.client_id + " Has Sent You A Screenshot";
mail.Body = String.Format(
    "<h3>Client: " + data.client_id + " Has Sent You A Screenshot</h3>" +
    @"<img src=""cid:{0}"" />", inline.ContentId);

mail.IsBodyHtml = true;
mail.Attachments.Add(att);

1
En realidad, no está agregando el LinkedResource al objeto de correo; en su lugar, lo está creando pero luego adjuntando un objeto Adjunto separado.
Adrian Wragg

4
El único problema con este código es que su string.Format hace referencia inline.ContentId, cuando en realidad debería ser att.ContentId. inlineno es necesario en absoluto. Prefiero tu pregunta a todas las respuestas, ya que realmente no necesitas usar un AlternateView.
Simon MᶜKenzie


Mi imagen se adjunta como extensión de archivo bin. ¿Estoy haciendo algo mal?
Miloš Đošović

Consulta este enlace. tiene un método listo para usar para múltiples archivos adjuntos en línea, así como para archivos adjuntos generales para archivos pdf / excel. stackoverflow.com/questions/33665280/…
kumar chandraketu

Respuestas:


61

Prueba esto

 string htmlBody = "<html><body><h1>Picture</h1><br><img src=\"cid:filename\"></body></html>";
 AlternateView avHtml = AlternateView.CreateAlternateViewFromString
    (htmlBody, null, MediaTypeNames.Text.Html);

 LinkedResource inline = new LinkedResource("filename.jpg", MediaTypeNames.Image.Jpeg);
 inline.ContentId = Guid.NewGuid().ToString();
 avHtml.LinkedResources.Add(inline);

 MailMessage mail = new MailMessage();
 mail.AlternateViews.Add(avHtml);

 Attachment att = new Attachment(filePath);
 att.ContentDisposition.Inline = true;

 mail.From = from_email;
 mail.To.Add(data.email);
 mail.Subject = "Client: " + data.client_id + " Has Sent You A Screenshot";
 mail.Body = String.Format(
            "<h3>Client: " + data.client_id + " Has Sent You A Screenshot</h3>" +
            @"<img src=""cid:{0}"" />", att.ContentId);

 mail.IsBodyHtml = true;
 mail.Attachments.Add(att);

25
Este código no funciona, use el siguiente código de @ T30, y tenga en cuenta que cuando agregue Vista alternativa a MailMessage, esa vista será el cuerpo de su correo electrónico y NO necesita completar la propiedad Body.
Eric

@Eric: hubo un pequeño problema en este código. en el mail.body solo use att.ContentId en lugar de inline.ContentId
Amir

153

Un código C # mínimo para incrustar una imagen puede ser:

MailMessage mailWithImg = getMailWithImg();
MySMTPClient.Send(mailWithImg); //* Set up your SMTPClient before!

private MailMessage getMailWithImg() {
    MailMessage mail = new MailMessage();
    mail.IsBodyHtml = true;
    mail.AlternateViews.Add(getEmbeddedImage("c:/image.png"));
    mail.From = new MailAddress("yourAddress@yourDomain");
    mail.To.Add("recipient@hisDomain");
    mail.Subject = "yourSubject";
    return mail;
}
private AlternateView getEmbeddedImage(String filePath) {
    LinkedResource res = new LinkedResource(filePath);
    res.ContentId = Guid.NewGuid().ToString();
    string htmlBody = @"<img src='cid:" + res.ContentId + @"'/>";
    AlternateView alternateView = AlternateView.CreateAlternateViewFromString(htmlBody, null, MediaTypeNames.Text.Html);
    alternateView.LinkedResources.Add(res);
    return alternateView;
}

3
Tuve que agregar un tipo mime para LinkedResourceque funcione en el cliente web de Hotmail / Outlook.com. FWIW, probé esto así como @Microsoft DN y funcionó mejor.
gregtheross

3
Para mí funciona, pero tuve que agregar ContentType: LinkedResource inline = new LinkedResource (filePath, MediaTypeNames.Image.Jpeg);
Washington da costa

5
Pequeño comentario: no es necesario llamar NewGuid(), la AttachmentBaseclase (que LinkedResourcehereda de) ya lo crea si es necesario.
Andrew

1
Agregue al LinkedResource el ContentType "image / bmp" para no recibir la imagen como un archivo adjunto.
Tanner Ornelas

1
@WilliamHumphries Creo que el recolector de basura ya maneja esto.
T30

9
    protected void Page_Load(object sender, EventArgs e)
    {
        string Themessage = @"<html>
                          <body>
                            <table width=""100%"">
                            <tr>
                                <td style=""font-style:arial; color:maroon; font-weight:bold"">
                               Hi! <br>
                                <img src=cid:myImageID>
                                </td>
                            </tr>
                            </table>
                            </body>
                            </html>";
        sendHtmlEmail("from@gmail.com", "tomailaccount", Themessage, "Scoutfoto", "Test HTML Email", "smtp.gmail.com", 25);
    }

    protected void sendHtmlEmail(string from_Email, string to_Email, string body, string           from_Name, string Subject, string SMTP_IP, Int32 SMTP_Server_Port)
    {
        //create an instance of new mail message
        MailMessage mail = new MailMessage();

        //set the HTML format to true
        mail.IsBodyHtml = true;

        //create Alrternative HTML view
        AlternateView htmlView = AlternateView.CreateAlternateViewFromString(body, null, "text/html");

        //Add Image
        LinkedResource theEmailImage = new LinkedResource("E:\\IMG_3332.jpg");
        theEmailImage.ContentId = "myImageID";

        //Add the Image to the Alternate view
        htmlView.LinkedResources.Add(theEmailImage);

        //Add view to the Email Message
        mail.AlternateViews.Add(htmlView);

        //set the "from email" address and specify a friendly 'from' name
        mail.From = new MailAddress(from_Email, from_Name);

        //set the "to" email address
        mail.To.Add(to_Email);

        //set the Email subject
        mail.Subject = Subject;

        //set the SMTP info
        System.Net.NetworkCredential cred = new System.Net.NetworkCredential("fromEmail@gmail.com", "fromEmail password");
        SmtpClient smtp = new SmtpClient("smtp.gmail.com", 587);
        smtp.EnableSsl = true;
        smtp.DeliveryMethod = SmtpDeliveryMethod.Network;
        smtp.UseDefaultCredentials = false;
        smtp.Credentials = cred;
        //send the email
        smtp.Send(mail);
    }

5

Además de los comentarios anteriores, tengo los siguientes comentarios adicionales:

  • No mezcle archivos adjuntos y AlternativeView, el uso de o el otro. Si los mezcla, los archivos adjuntos en línea se procesarán como descargas desconocidas.
  • Si bien Outlook y Google permiten el estilo HTML estándar, "cid:att-001"esto NO funciona en iPhone (nivel de parche de finales de 2016), más bien use alfanumérico puro"cid:att-001" -> "cid:att001"

Como un aparte. La representación de Outlook (incluso Office 2015) (todavía la clara mayoría para los usuarios de negocios) requiere el uso de HTML estilo TABLE TR TD ya que no es totalmente compatible con el modelo de cuadro HTML.


Genial, estoy impresionado por su investigación.
Hammad Sajid

Este sigue siendo el caso en 2020, solo tuve que reemplazar todo el código LinkedResource / AlternativeView con código adjunto porque también necesitaba archivos adjuntos, y esta publicación parece ser la única cosa en todo Internet que menciona que eso no funcionará
Whelkaholism

5

Un ejemplo aún más minimalista:

var linkedResource = new LinkedResource(@"C:\Image.jpg", MediaTypeNames.Image.Jpeg);

// My mail provider would not accept an email with only an image, adding hello so that the content looks less suspicious.
var htmlBody = $"hello<img src=\"cid:{linkedResource.ContentId}\"/>";
var alternateView = AlternateView.CreateAlternateViewFromString(htmlBody, null, MediaTypeNames.Text.Html);
alternateView.LinkedResources.Add(linkedResource);

var mailMessage = new MailMessage
{
    From = new MailAddress("youremail@host.com"),
    To = { "recipient@host.com" },
    Subject = "yourSubject",
    AlternateViews = { alternateView }
};

var smtpClient = new SmtpClient();
smtpClient.Send(mailMessage);

3

Prueba esto.


protected void Page_Load(object sender, EventArgs e)
        {
            string Themessage = @"<html>
                              <body>
                                <table width=""100%"">
                                <tr>
                                    <td style=""font-style:arial; color:maroon; font-weight:bold"">
                                   Hi! <br>
                                    <img src=cid:myImageID>
                                    </td>
                                </tr>
                                </table>
                                </body>
                                </html>";
            sendHtmlEmail("from@gmail.com", "tomailaccount", Themessage, "Scoutfoto", "Test HTML Email", "smtp.gmail.com", 25);
        }

protected void sendHtmlEmail(string from_Email, string to_Email, string body, string from_Name, string Subject, string SMTP_IP, Int32 SMTP_Server_Port)
        {
            //create an instance of new mail message
            MailMessage mail = new MailMessage();

            //set the HTML format to true
            mail.IsBodyHtml = true;

            //create Alrternative HTML view
            AlternateView htmlView = AlternateView.CreateAlternateViewFromString(body, null, "text/html");

            //Add Image
            LinkedResource theEmailImage = new LinkedResource("E:\\IMG_3332.jpg");
            theEmailImage.ContentId = "myImageID";

            //Add the Image to the Alternate view
            htmlView.LinkedResources.Add(theEmailImage);

            //Add view to the Email Message
            mail.AlternateViews.Add(htmlView);

            //set the "from email" address and specify a friendly 'from' name
            mail.From = new MailAddress(from_Email, from_Name);

            //set the "to" email address
            mail.To.Add(to_Email);

            //set the Email subject
            mail.Subject = Subject;

            //set the SMTP info
            System.Net.NetworkCredential cred = new System.Net.NetworkCredential("fromEmail@gmail.com", "fromEmail password");
            SmtpClient smtp = new SmtpClient("smtp.gmail.com", 587);
            smtp.EnableSsl = true;
            smtp.DeliveryMethod = SmtpDeliveryMethod.Network;
            smtp.UseDefaultCredentials = false;
            smtp.Credentials = cred;
            //send the email
            smtp.Send(mail);
        }

1

Necesita agregar el LinkedResource en un AlternateView

AlternateView alternateView = AlternateView.CreateAlternateViewFromString("<h3>Client: " + data.client_id + " Has Sent You A Screenshot</h3>" +
                @"<img src=""cid:{0}"" />", null, "text/html");
alternateView.LinkedResources.Add(inline);
mail.AlternateViews.Add(alternateView);

1
    MailMessage mail = new MailMessage();
    //set the addresses
    mail.From = new MailAddress("userid@gmail.com");
    mail.To.Add("userid@gmail.com");

    //set the content
    mail.Subject = "Sucessfully Sent the HTML and Content of mail";

    //first we create the Plain Text part
    string plainText = "Non-HTML Plain Text Message for Non-HTML enable mode";
    AlternateView plainView = AlternateView.CreateAlternateViewFromString(plainText, null, "text/plain");
    XmlTextReader reader = new XmlTextReader(@"E:\HTMLPage.htm");
    string[] address = new string[30];
    string finalHtml = "";
    var i = -1;
    while (reader.Read())
    {
        if (reader.NodeType == XmlNodeType.Element)
        { // The node is an element.
            if (reader.AttributeCount <= 1)
            {
                if (reader.Name == "img")
                {
                    finalHtml += "<" + reader.Name;
                    while (reader.MoveToNextAttribute())
                    {
                        if (reader.Name == "src")
                        {
                            i++;
                            address[i] = reader.Value;
                            address[i] = address[i].Remove(0, 8);
                            finalHtml += " " + reader.Name + "=" + "cid:chartlogo" + i.ToString();
                        }
                        else
                        {
                            finalHtml += " " + reader.Name + "='" + reader.Value + "'";
                        }
                    }
                    finalHtml += ">";
                }
                else
                {
                    finalHtml += "<" + reader.Name;
                    while (reader.MoveToNextAttribute())
                    {
                        finalHtml += " " + reader.Name + "='" + reader.Value + "'";
                    }
                    finalHtml += ">";
                }
            }

        }
        else if (reader.NodeType == XmlNodeType.Text)
        { //Display the text in each element.
            finalHtml += reader.Value;
        }
        else if (reader.NodeType == XmlNodeType.EndElement)
        {
            //Display the end of the element.
            finalHtml += "</" + reader.Name;
            finalHtml += ">";
        }

    }

    AlternateView htmlView = AlternateView.CreateAlternateViewFromString(finalHtml, null, "text/html");
    LinkedResource[] logo = new LinkedResource[i + 1];
    for (int j = 0; j <= i; j++)
    {
        logo[j] = new LinkedResource(address[j]);
        logo[j].ContentId = "chartlogo" + j;
        htmlView.LinkedResources.Add(logo[j]);
    }
    mail.AlternateViews.Add(plainView);
    mail.AlternateViews.Add(htmlView);
    SmtpClient smtp = new SmtpClient();
    smtp.Host = "smtp.gmail.com";
    smtp.Port = 587;
    smtp.Credentials = new NetworkCredential(
        "userid@gmail.com", "Password");
    smtp.EnableSsl = true;
    Console.WriteLine();
    smtp.Send(mail);
}

1

La otra solución es adjuntar la imagen como archivo adjunto y luego hacer referencia al código html usando cid. Código HTML:

<html>
<head>
</head>
<body>
    <img width=100 height=100 id=""1"" src=""cid:Logo.jpg"">
</body>
</html>

Código C #:

EmailMessage email = new EmailMessage(service);
email.Subject = "Email with Image";
email.Body = new MessageBody(BodyType.HTML, html);
email.ToRecipients.Add("abc@xyz.com");
string file = @"C:\Users\acv\Pictures\Logo.jpg";
email.Attachments.AddFileAttachment("Logo.jpg", file);
email.Attachments[0].IsInline = true;
email.Attachments[0].ContentId = "Logo.jpg";
email.SendAndSaveCopy();

0

enviando 2 imágenes convertidor de código vb.net para convertidor en línea C #.

Public Function SendEmail(Optional ByVal p_AsHTML As Boolean = False, Optional ByVal p_themEmail As String = "") As Boolean
            Dim client As SmtpClient = New SmtpClient ''("FMSERVER.FMINNOVATIONS.COM.AU")
            'Dim fromAddress As MailAddress = New MailAddress(Me.FromEmail, "WSMenterprise")
            'Dim toAddress As MailAddress
            Try
                Dim aMessage As New MailMessage()
                '(New MailAddress(Me.FromEmail, "WSMenterprise"), New MailAddress(anAdd))
                If _fromAddress IsNot Nothing Then
                    If _fromName IsNot Nothing Then
                        aMessage.From = New MailAddress(_fromAddress, _fromName)
                    Else
                        aMessage.From = New MailAddress(_fromAddress)
                    End If
                End If
                For Each anAdd As String In _To
                    aMessage.To.Add(New MailAddress(anAdd))
                Next
                For Each cc As String In _CC
                    aMessage.CC.Add(New MailAddress(cc))
                Next
                For Each bcc As String In _BCC
                    aMessage.Bcc.Add(New MailAddress(bcc))
                Next
                aMessage.Subject = _Subject
                aMessage.IsBodyHtml = p_AsHTML

                If _EmailLogo Is Nothing Then
                    aMessage.Body = _Body
                Else
                    If p_themEmail.ToString().ToLower.Contains("dexus") Then

                       Dim htmlView = AlternateView.CreateAlternateViewFromString(_Body.ToString(), Nothing, "text/html")
                        Dim logo As New LinkedResource(_EmailLogo)
                        logo.ContentId = "Dexuslogo1"
                        Dim logo1 As New LinkedResource(_EmailLogo1)
                        logo1.ContentId = "Dexuslogo2"
                        htmlView.LinkedResources.Add(logo)
                        htmlView.LinkedResources.Add(logo1)
                        aMessage.AlternateViews.Add(htmlView)

                    Else

                        Dim htmlView = AlternateView.CreateAlternateViewFromString(_Body.ToString(), Nothing, "text/html")
                        Dim logo As New LinkedResource(_EmailLogo)
                        logo.ContentId = "companylogo"
                        htmlView.LinkedResources.Add(logo)
                        aMessage.AlternateViews.Add(htmlView)
                    End If
                End If

                For Each anAttach As Attachment In _Attachments
                    aMessage.Attachments.Add(anAttach)
                Next

                If _ReplyTo IsNot Nothing Then aMessage.ReplyToList.Add(New MailAddress(_ReplyTo))
                client.Host = "smtpi.cbre.com.au"
                client.UseDefaultCredentials = True
                client.Send(aMessage)
            Catch exRecipUnk As SmtpFailedRecipientException
                Return False
            Catch exSmtp As SmtpException
                ''exSmtp.StatusCode
                Return False
            Catch ex As Exception
                Return False
            End Try
            Return True
        End Function
    If p_Gmap_code = "DE" Then
                Dim p_Theme As New Theme("Dexus")
                Dim passwordlink As String = ""
                Dim DexuslogoImage1 As String = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Images\Dexus_Notice_Logo.png")
                Dim DexuslogoImage2 As String = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Images\DexusTenantNotice.png")

                passwordlink = "<a href='" + p_Theme.TenantLoginPage + "?accesstype=email&te=" + a.Encrypt(p_TenantEmail) + "' target='_blank'>here.</a><br/>"
                bodys += "<div align='Center'><table border='0' cellpadding='0' cellspacing='0'><tr style='height:50px;'><td width='623px' ></td><td valign='top' width='180'><p align='right'><a href='http://www.dexus.com/'><img border='0' height='50' src=cid:Dexuslogo1 width='174' alt=''/></a></p></td></tr><tr><td colspan='2' width='803' style='height:25px;'></td></tr> <tr><td width='623px'><p align='left' style='font-family:Arial;font-size:14pt;'><strong> Your Dexus Response Password is about to expire</strong></p></td>"
                bodys += " <td width='180'><p align='right' style='font-family:Arial;font-size:10pt;'>" + DateTime.Now.ToString("dd/MM/yyyy") + " </p>"
                bodys += "</td></tr><tr><td colspan='2' width='803' style='height:30px;'>  </td></tr> <tr>  <td colspan='2' width='803' style='font-family:Arial;font-size:10pt;'>"
                bodys += "<p>" + wishes + " " + p_TenantName.Trim().ToString() + "</p>"
                bodys += "</td></tr><tr><td colspan='2' width='803' style='height:25px;'></td> </tr><tr><td colspan='2' width='803' style='font-family:Arial;font-size:10pt;'>"
                bodys += "Your Dexus Response password is about to expire in " + p_remaindays.ToString() + " days.<br /><br /> To reset your password and update your details, please click " + passwordlink.ToString() + "<br /><br />Please note that if you do not update your password by " + p_date + ",then your account will be set to inactive and you will not be able to access Dexus Response.</br></br>Please contact Dexus Response if you require assistance in accessing the portal.</p></td>" 'edit
                bodys += " </tr><tr><td colspan='2' width='803' style='height:30px;'></td></tr><tr><td colspan='2' width='803'><table align='left' border='0' cellpadding='0' cellspacing='0'><tr><td width='802' style='font-family:Arial;font-size:10pt;'><p><strong>Dexus Response</strong></p></td></tr><tr><td width='802' style='font-family:Arial;font-size:10pt;'><p><a href='mailto:property.services@dexusfm.com'>property.services@dexusfm.com</a> <strong>|</strong> 1300 339 870 <strong>|</strong> <a href='https://response.dexus.com/'>response.dexus.com</a></p></td></tr></table></td></tr><tr><td colspan='2' width='803' style='height:15px;'></td></tr><tr> <td colspan='2' width='803'><p> </p><p><a href='https://response.dexus.com/' border='0' target='_blank'><img border='0' height='133'"
                bodys += "src=cid:Dexuslogo2 alt='' width='800' /></a></p></td></tr><tr><td colspan='2' width='803' style='height:10px;'></td></tr><tr><td colspan='2' width='803' style='font-family:Arial;font-size:10pt;'><p><a href='http://www.dexus.com/who-we-are/terms-and-conditions' style=' color:#000000;'>Terms and Conditions</a><strong> | </strong><a href='http://www.dexus.com/who-we-are/privacy-policy' style=' color:#000000;'> Privacy Policy</a></p></td></tr><tr><td colspan='2' width='803' style='height:40px;'></td></tr><tr><td colspan='2' width='803'><p></p></td></tr><tr><td colspan='2' width='803' style='height:10px;'></td></tr><tr></tr><tr><td colspan='2' width='803' style='height:20px;'></td></tr></table></div>"

                email = New Common.Email(emailHeading, bodys, p_Theme.EmailFrom, DexuslogoImage1, DexuslogoImage2)
                email.ToEmail = p_TenantEmail
                email.SendEmail(True, p_Theme.EmailFrom)

0

Todos tenemos nuestros estilos de codificación preferidos. Esto es lo que hice:

var pictures = new[]
{
    new { id = Guid.NewGuid(), type = "image/jpeg", tag = "justme", path = @"C:\Pictures\JustMe.jpg" },
    new { id = Guid.NewGuid(), type = "image/jpeg", tag = "justme-bw", path = @"C:\Pictures\JustMe-BW.jpg" }
}.ToList();

var content = $@"
<style type=""text/css"">
    body {{ font-family: Arial; font-size: 10pt; }}
</style>
<body>
<h4>{DateTime.Now:dddd, MMMM d, yyyy h:mm:ss tt}</h4>
<p>Some pictures</p>
<div>
    <p>Color Picture</p>
    <img src=cid:{{justme}} />
</div>
<div>
    <p>Black and White Picture</p>
    <img src=cid:{{justme-bw}} />
</div>
<div>
    <p>Color Picture repeated</p>
    <img src=cid:{{justme}} />
</div>
</body>
";

// Update content with picture guid
pictures.ForEach(p => content = content.Replace($"{{{p.tag}}}", $"{p.id}"));
// Create Alternate View
var view = AlternateView.CreateAlternateViewFromString(content, Encoding.UTF8, MediaTypeNames.Text.Html);
// Add the resources
pictures.ForEach(p => view.LinkedResources.Add(new LinkedResource(p.path, p.type) { ContentId = p.id.ToString() }));

using (var client = new SmtpClient()) // Set properties as needed or use config file
using (MailMessage message = new MailMessage()
{
    IsBodyHtml = true,
    BodyEncoding = Encoding.UTF8,
    Subject = "Picture Email",
    SubjectEncoding = Encoding.UTF8,
})
{
    message.AlternateViews.Add(view);
    message.From = new MailAddress("me@me.com");
    message.To.Add(new MailAddress("you@you.com"));
    client.Send(message);
}

0

Agregué el código completo a continuación para mostrar imágenes en Gmail, Thunderbird y otros clientes de correo electrónico:

MailMessage mailWithImg = getMailWithImg();
MySMTPClient.Send(mailWithImg); //* Set up your SMTPClient before!

private MailMessage getMailWithImg()
{
    MailMessage mail = new MailMessage();
    mail.IsBodyHtml = true;
    mail.AlternateViews.Add(getEmbeddedImage("c:/image.png"));
    mail.From = new MailAddress("yourAddress@yourDomain");
    mail.To.Add("recipient@hisDomain");
    mail.Subject = "yourSubject";
    return mail;
}
private AlternateView getEmbeddedImage(String filePath)
 {
    // below line was corrected to include the mediatype so it displays in all 
    // mail clients. previous solution only displays in Gmail the inline images 
    LinkedResource res = new LinkedResource(filePath, MediaTypeNames.Image.Jpeg);  
    res.ContentId = Guid.NewGuid().ToString();
    string htmlBody = @"<img src='cid:" + res.ContentId + @"'/>";
    AlternateView alternateView = AlternateView.CreateAlternateViewFromString(htmlBody,  
     null, MediaTypeNames.Text.Html);
    alternateView.LinkedResources.Add(res);
    return alternateView;
}
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.