开发者

Send html email with embedded image and plain text with same image as attachment in C#

开发者 https://www.devze.com 2023-03-17 09:16 出处:网络
I wish to send an email, with a plain text and html version.The email needs an image to go 开发者_如何学Pythonwith it (not one I can host somewhere else), it should be embedded if the client views it

I wish to send an email, with a plain text and html version. The email needs an image to go 开发者_如何学Pythonwith 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).


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);
    }
}


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("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);
0

精彩评论

暂无评论...
验证码 换一张
取 消