发送包含嵌入图像和纯文本的html电子邮件,其中包含与C#中的附件相同的图像

时间:2011-07-04 16:26:11

标签: c# email html-email system.net.mail

我希望发送一封包含纯文本和html版本的电子邮件。电子邮件需要一个图像(不是我可以在其他地方托管),如果客户端在html中查看它,则应该嵌入它,并附加到纯文本视图。

这可能会在所有普通客户中发挥作用吗?

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

2 个答案:

答案 0 :(得分:6)

此代码段适用于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);
    }
}

答案 1 :(得分:1)

纯文本视图,正是如此。它是纯文本,没有可见的图像。你可以附上一张图片,但你不能让它们查看它。

查看原始电子邮件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);