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

后端 未结 2 766
走了就别回头了
走了就别回头了 2020-12-18 17:08

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

相关标签:
2条回答
  • 2020-12-18 17:25

    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);
        }
    }
    
    0 讨论(0)
  • 2020-12-18 17:31

    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 讨论(0)
提交回复
热议问题