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

发布于 2024-11-18 16:02:53 字数 227 浏览 3 评论 0原文

我希望发送一封电子邮件,包含纯文本和 html 版本。该电子邮件需要附带一张图像(我不能在其他地方托管该图像),如果客户以 html 形式查看它,则应将其嵌入,并为纯文本视图附加该图像。

这是否可能适用于所有普通客户端?

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

I wish to send an email, with a plain text and html version. The email needs an image to go with it (not one I can host somewhere else), it should be embedded if the client views it in html, and attached for the plain text view.

Is this possible to do that would work in all common clients?

The closest I have come is creating the image as an attachment (rather than a linked resource) then referencing it in the html with cid:filename.jpg. However this doesn't work in gmail (it doesn't display the image in the html).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

幽梦紫曦~ 2024-11-25 16:02:53

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

This code snippet works in outlook 2010 and gmail. I test the plain text email by temporarily putting the plain text part last in the email, which makes gmail use that.

It also demonstrates some other cool stuff such as email templates and tag substitution.


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);
    }
}
哎呦我呸! 2024-11-25 16:02:53

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

查看 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("[email protected]", "From guy");
m.To.Add(new MailAddress("[email protected]", "To guy"));
m.Subject = "A picture using alternate views";
SmtpClient client = new SmtpClient("mysmtphost.com");
client.Send(m);

Plain text view, is exactly that. It is plain text, it has no images visible. You can attach a picture, but you cant make them view it.

Take a look at the raw email outlook sends for example on how to show inline attachments. As an example heres some code someone else did: http://blog.devexperience.net/en/12/Send_an_Email_in_CSharp_with_Inline_attachments.aspx

-- Apparently the above link is no longer valid - a quick google provided the following example to inline a picture

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("[email protected]", "From guy");
m.To.Add(new MailAddress("[email protected]", "To guy"));
m.Subject = "A picture using alternate views";
SmtpClient client = new SmtpClient("mysmtphost.com");
client.Send(m);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文