在C#中发送带有嵌入图像的html电子邮件和带有相同图像的纯文本作为附件

本文关键字:图像 文本 电子邮件 html | 更新日期: 2023-09-27 18:01:12

我想发送一封纯文本和html版本的电子邮件。电子邮件需要一个图像(而不是我可以在其他地方托管的图像(,如果客户端以html格式查看,则应该嵌入该图像,并为纯文本视图附加该图像。

这有可能在所有普通客户中都有效吗?

我最接近的方法是将图像创建为附件(而不是链接资源(,然后在html中用cid:filename.jpg引用它。然而,这在gmail中不起作用(它不会在html中显示图像(。

在C#中发送带有嵌入图像的html电子邮件和带有相同图像的纯文本作为附件

此代码片段适用于outlook 2010和gmail。我通过暂时将纯文本部分放在电子邮件的最后来测试纯文本电子邮件,这使得gmail使用了它。

它还展示了一些其他很酷的东西,比如电子邮件模板和标签替换。


public void SendEmailWithPicture(string email, byte[] image)
{
    string filename = "AttachmentName.jpg";
    LinkedResource linkedResource = new LinkedResource(new MemoryStream(image), "image/jpg");
    linkedResource.ContentId = filename;
    linkedResource.ContentType.Name = filename;
    this.Send(
        EmailTemplates.sendpicture,
        this.Subjects.SendPicture,
        new List() { email },
        this.ReplyTo,
        tagValues: new Dictionary() { { "ImageAttachmentName", "cid:" + filename } },
        htmlLinkedResources: new List() { linkedResource }
        );
}
private void Send(EmailTemplates template, string subject, List to, string replyTo,
    Dictionary tagValues = null, List attachments = null, List htmlLinkedResources = null)
{
    try
    {
        MailMessage mailMessage = new MailMessage();
        // Set up the email header.
        to.ForEach(t => mailMessage.To.Add(new MailAddress(t)));
        mailMessage.ReplyToList.Add(new MailAddress(replyTo));
        mailMessage.Subject = subject;
        string fullTemplatePath = Path.Combine(this.TemplatePath, EMAIL_TEMPLATE_PATH);
        // Load the email bodies
        var htmlBody = File.ReadAllText(Path.Combine(fullTemplatePath, Path.ChangeExtension(template.ToString(), "html")));
        var textBody = File.ReadAllText(Path.Combine(fullTemplatePath, Path.ChangeExtension(template.ToString(), "txt")));
        // Replace the tags in the emails
        if (tagValues != null)
        {
            foreach (var entry in tagValues)
            {
                string tag = "{{" + entry.Key + "}}";
                htmlBody = htmlBody.Replace(tag, entry.Value);
                textBody = textBody.Replace(tag, entry.Value);
            }
        }
        // Create plain text alternative view
        string baseTxtTemplate = File.ReadAllText(Path.Combine(fullTemplatePath, TXT_BASE_TEMPLATE));
        textBody = baseTxtTemplate.Replace(TAG_CONTENT, textBody);
        AlternateView textView = AlternateView.CreateAlternateViewFromString(textBody, new System.Net.Mime.ContentType("text/plain"));
        // Create html alternative view
        string baseHtmlTemplate = File.ReadAllText(Path.Combine(fullTemplatePath, HTML_BASE_TEMPLATE));
        htmlBody = baseHtmlTemplate.Replace(TAG_CONTENT, htmlBody);
        AlternateView htmlView = AlternateView.CreateAlternateViewFromString(htmlBody, new System.Net.Mime.ContentType("text/html"));
        // Add any html linked resources
        if (htmlLinkedResources != null)
        {
            htmlLinkedResources.ForEach(lr => htmlView.LinkedResources.Add(lr));
            htmlLinkedResources.ForEach(lr => textView.LinkedResources.Add(lr));
        }
        // Add the two views (gmail will always display plain text version if its added last)
        mailMessage.AlternateViews.Add(textView);
        mailMessage.AlternateViews.Add(htmlView);
        // Add any attachments
        if (attachments != null)
        {
            attachments.ForEach(a => mailMessage.Attachments.Add(a));
        }
        // Send the email.
        SmtpClient smtp = new SmtpClient();
        smtp.Send(mailMessage);
    }
    catch (Exception ex)
    {
        throw new Exception(String.Format("Error sending email (to:{0}, replyto:{1})", String.Join(",", to), replyTo), ex);
    }
}

纯文本视图就是这样。它是纯文本,没有可见的图像。你可以附加图片,但不能让他们观看。

看看outlook发送的原始电子邮件,例如如何显示内联附件。作为一个例子,这里有一些其他人做的代码:http://blog.devexperience.net/en/12/Send_an_Email_in_CSharp_with_Inline_attachments.aspx

--显然,上面的链接不再有效-一个快速的谷歌提供了以下例子来内联图片

string htmlBody = "<html><body><h1>Picture</h1><br><img src='"cid:Pic1'"></body></html>";
AlternateView avHtml = AlternateView.CreateAlternateViewFromString
    (htmlBody, null, MediaTypeNames.Text.Html);
// Create a LinkedResource object for each embedded image
LinkedResource pic1 = new LinkedResource("pic.jpg", MediaTypeNames.Image.Jpeg);
pic1.ContentId = "Pic1";
avHtml.LinkedResources.Add(pic1);

// Add the alternate views instead of using MailMessage.Body
MailMessage m = new MailMessage();
m.AlternateViews.Add(avHtml);
// Address and send the message
m.From = new MailAddress("email1@host.com", "From guy");
m.To.Add(new MailAddress("email2@host.com", "To guy"));
m.Subject = "A picture using alternate views";
SmtpClient client = new SmtpClient("mysmtphost.com");
client.Send(m);