26

I am using MailKit/MimeKit 1.2.7 (latest NuGet version).

I tried to embed an image in the HTML body of my email by following the sample from the API documentation (section "Using a BodyBuilder").

My current code looks like this:

 var builder = new BodyBuilder();

 builder.HtmlBody = @"<p>Hey!</p><img src=""Image.png"">";

 var pathImage = Path.Combine(Misc.GetPathOfExecutingAssembly(), "Image.png");
 builder.LinkedResources.Add(pathLogoFile);
 message.Body = builder.ToMessageBody();

I can send this email and in fact the image is attached to the email. But it is not embedded.

Am I missing something? Or is this Apple Mail's fault (this is the email client I am using for receiving emails)?

I am grateful for any idea (and thanks so much to Jeffrey Stedfast for providing such a great toolset!!).

Ingmar

jstedfast
  • 35,744
  • 5
  • 97
  • 110
Ingmar
  • 1,525
  • 6
  • 34
  • 51

2 Answers2

52

Try something a bit more like this:

var builder = new BodyBuilder ();
var pathImage = Path.Combine (Misc.GetPathOfExecutingAssembly (), "Image.png");
var image = builder.LinkedResources.Add (pathLogoFile);

image.ContentId = MimeUtils.GenerateMessageId ();

builder.HtmlBody = string.Format (@"<p>Hey!</p><img src=""cid:{0}"">", image.ContentId);

message.Body = builder.ToMessageBody ();

If this works for you, I'll update the documentation.

The problem might be that Apple's multipart/related implementation does not resolve the Image.png reference using the Content-Location header on the image mime part (possibly because it is a relative URL).

The cid: URL-type should work, though, but it's a bit more awkward to construct since you need to know the Content-Id values for each image attachment.

jstedfast
  • 35,744
  • 5
  • 97
  • 110
  • Good morning. And thanks for your tip. Works great! In fact I have been using the cid: stuff with my old email component as well (before switching to MailKit). So, this solution is perfect for me. THX again. – Ingmar Jul 15 '15 at 06:55
  • I ran into a couple more issues though today. I will put them in separate questions/posts here on stackoverflow and would be more than happy if you had a couple more easy solutions for me :) – Ingmar Jul 15 '15 at 06:57
  • I'm having problems with embedded images. I use basically the same approach. BodyBuilder.LinkedResources.Add() The attachment arrives. But its marked as a regular attachment and not 'inline'. In my own client I see the ContentDiposition and looks like a regular attachment. Outlook, still renders the image but also shows an attachment icon in the email list as if the email had regular attachments. Any idea? – bitdisaster Sep 03 '15 at 00:58
  • Fixed: https://github.com/jstedfast/MimeKit/commit/7134e0542f39ccb290cb34db89290937f1916762 – jstedfast Sep 03 '15 at 11:47
  • I explicitly set IsAttachment = false on the MimeEntity that is returned by BodyBuilder.LinkedResources.Add() before sending. Is your fix doing anything else. If not I would still expect the same behavior. – bitdisaster Sep 03 '15 at 19:49
  • Can you paste the raw message in your question? Without it, all I can do is guess at the problem. – jstedfast Sep 04 '15 at 17:30
  • Actually, n/m, this is your problem: `builder.HtmlBody = @"

    Hey!

    ";` While it is legal to refer to images by name, some clients do not handle it well. Instead, I would recommend referring to them by their `Content-Id` header value using the following syntax: ``
    – jstedfast Sep 04 '15 at 17:31
  • It's worth mentioning that the cid:identifier must be URL encoded as per RFC2392, even though this behaviour is only properly documented in the errata of that RFC (!). This caused me a quite a bit of pain producing compliant emails, until I found this out. – pattermeister Nov 14 '16 at 09:22
  • Hello, I have also problem of embedding images in html template, I have one html template, and I am using this template to send email body part, I have used your above code and added LinkedResources and set in my html template as like this : and in the code side, i have write as like this : var image = builder.LinkedResources.Add(logoPath); image.ContentId = "companylogo"; But still, I am not getting embedded images in my email – Herin Feb 27 '17 at 10:20
  • Any examples for in-memory images with no path? – Jon Freynik Jun 06 '22 at 06:42
  • Yes, use any of the AttachmentCollection.Add() methods that take a Stream or byte[]. The `fileName` parameter in those methods is just used for naming the attachment, it is not opened or read at all. – jstedfast Jun 06 '22 at 15:04
5

Just for reference, this can be found under http://www.mimekit.net/docs/html/Creating-Messages.htm now. The link in the original answer is broken.

FranzHuber23
  • 3,311
  • 5
  • 24
  • 63