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

Spr*_*tar 0 c# email html-email system.net.mail

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

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

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

Spr*_*tar 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 使用文件名作为CID是不安全的 - 例如,它可以包含空格,特别是在Gmail中不会显示图像.最好的选择是Guid.NewGuid().ToString() (4认同)