Отправить встроенное изображение по электронной почте


106

Возникла проблема с отправкой изображения по электронной почте в виде встроенного изображения в тело. Файл изображения отображается как вложение, что нормально, но часть встроенного изображения отображается просто красным крестиком.

Вот что у меня есть

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
Фактически вы не добавляете LinkedResource к почтовому объекту; вместо этого вы создаете его, но затем присоединяете отдельный объект Attachment.
Адриан Рэгг,

4
Единственная проблема с этим кодом заключается в том, что ваша string.Format ссылается на то inline.ContentId, что на самом деле должно быть att.ContentId. inlineсовсем не требуется. Я предпочитаю ваш вопрос всем ответам, поскольку вам действительно не нужно использовать расширение AlternateView.
Саймон MᶜKenzie


Мое изображение прикрепляется как расширение файла bin. Я делаю что-то неправильно?
Милош Джошович

Проверьте эту ссылку. у него есть готовый метод для множественного встроенного вложения, а также для общего вложения для файлов pdf / excel. stackoverflow.com/questions/33665280/…
kumar chandraketu

Ответы:


61

Попробуй это

 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
Этот код не работает, используйте приведенный ниже код из @ T30 и имейте в виду, когда вы добавляете альтернативное представление в MailMessage, это представление будет телом вашего электронного письма, и вам НЕ нужно заполнять свойство Body.
Эрик

@Eric: в этом коде была небольшая проблема. в mail.body просто используйте att.ContentId вместо inline.ContentId
Амир

154

Некоторый минимальный код C # для встраивания изображения может быть:

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
Мне пришлось добавить MIME-тип, LinkedResourceчтобы он работал в веб-клиенте Hotmail / Outlook.com. FWIW, я пробовал это, а также @Microsoft DN, и это сработало лучше.
gregtheross

3
Для меня это работает, но мне пришлось добавить ContentType: LinkedResource inline = new LinkedResource (filePath, MediaTypeNames.Image.Jpeg);
Вашингтон-да-Коста,

5
Небольшой комментарий: вызывать не нужно NewGuid(), AttachmentBaseкласс ( LinkedResourceнаследующий от) уже при необходимости его создает.
Эндрю

1
Добавьте в LinkedResource ContentType «image / bmp», чтобы не получать изображение в виде прикрепленного файла.
Таннер Орнелас

1
@WilliamHumphries Я думаю, что сборщик мусора уже справляется с этим.
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

В дополнение к комментариям выше у меня есть следующие дополнительные комментарии:

  • Не смешивайте Attachments и AlternativeView, использование или другое. Если вы их смешаете, встроенные вложения будут отображаться как неизвестные загрузки.
  • Хотя Outlook и Google допускают стандартный стиль HTML, "cid:att-001"это НЕ работает на iPhone (уровень исправлений конца 2016 года), вместо этого используйте чисто буквенно-цифровые"cid:att-001" -> "cid:att001"

Как в сторону. Визуализация Outlook (даже Office 2015) (по-прежнему явное большинство для деловых пользователей) требует использования HTML в стиле TABLE TR TD, поскольку он не полностью поддерживает блочную модель HTML.


Отлично, я впечатлен вашим исследованием.
Хаммад Саджид,

Это по-прежнему актуально в 2020 году, просто пришлось заменить весь код LinkedResource / AlternativeView кодом вложения, потому что мне также нужны были файловые вложения, и этот пост, кажется, единственное, что во всем Интернете упоминает, что это не сработает
Велоголизм

5

Еще более минималистичный пример:

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

Попробуй это.


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

Вам нужно добавить LinkedResource в 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

Другое решение - прикрепить изображение как вложение, а затем ссылаться на его html-код с помощью cid. HTML-код:

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

Код 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

отправка 2 изображений vb.net code convert для онлайн-конвертера 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

У всех нас есть предпочтительные стили кодирования. Вот что я сделал:

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

Я добавил полный код ниже для отображения изображений в Gmail, Thunderbird и других почтовых клиентах:

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;
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.