How to embed multiple images in email body using .NET

First, you could try to use absolute URIs to embedded images. Here is example from RFC-2557:

  From: [email protected]
  To: [email protected]
  Subject: A simple example
  Mime-Version: 1.0
  Content-Type: multipart/related; boundary="boundary-example";
          type="text/html"; start="<foo3@[email protected]>"

  --boundary-example
  Content-Type: text/html;charset="US-ASCII"
  Content-ID: <foo3@[email protected]>

  ... text of the HTML document, which might contain a URI
  referencing a resource in another body part, for example
  through a statement such as:
  <IMG SRC="http://www.ietf.cnri.reston.va.us/images/ietflogo.gif" ALT="IETF logo">

  --boundary-example
  Content-Location:
     http://www.ietf.cnri.reston.va.us/images/ietflogo.gif
  Content-Type: IMAGE/GIF
  Content-Transfer-Encoding: BASE64

  R0lGODlhGAGgAPEAAP/////ZRaCgoAAAACH+PUNvcHlyaWdodCAoQykgMTk5
  NSBJRVRGLiBVbmF1dGhvcml6ZWQgZHVwbGljYXRpb24gcHJvaGliaXRlZC4A
  etc...

  --boundary-example--

You just need to assign LinkedResource.ContentLink property instead of ContentId.

Second, you could embed images directly to your html with the "data" URL scheme.

    <IMG
    SRC="data:image/gif;base64,R0lGODdhMAAwAPAAAAAAAP///ywAAAAAMAAw
    AAAC8IyPqcvt3wCcDkiLc7C0qwyGHhSWpjQu5yqmCYsapyuvUUlvONmOZtfzgFz
    ByTB10QgxOR0TqBQejhRNzOfkVJ+5YiUqrXF5Y5lKh/DeuNcP5yLWGsEbtLiOSp
    a/TPg7JpJHxyendzWTBfX0cxOnKPjgBzi4diinWGdkF8kjdfnycQZXZeYGejmJl
    ZeGl9i2icVqaNVailT6F5iJ90m6mvuTS4OK05M0vDk0Q4XUtwvKOzrcd3iq9uis
    F81M1OIcR7lEewwcLp7tuNNkM3uNna3F2JQFo97Vriy/Xl4/f1cf5VWzXyym7PH
    hhx4dbgYKAAA7"
    ALT="Larry">

BTW, your html markup is not well-formed. You may also be interested in “foreach” vs “ForEach”


The other way to embed images in E-mail when using System.Net.Mail is

Attach image from local drive to email and assign a contentID to it and later use this contentID in the image URL.

This can be done by:

var contentID = "Image";
var inlineLogo = new Attachment(@"C:\Desktop\Image.jpg");
inlineLogo.ContentId = contentID;
inlineLogo.ContentDisposition.Inline = true;
inlineLogo.ContentDisposition.DispositionType = DispositionTypeNames.Inline;

msg.IsBodyHtml = true;
msg.Attachments.Add(inlineLogo);
msg.Body = "<htm><body> <img src=\"cid:" + contentID + "\"> </body></html>";

So, I think figured out what the actual problem is Its in this line

// Alternate view for embedded images
    AlternateView avText = AlternateView.CreateAlternateViewFromString(metric.Name, null, MediaTypeNames.Text.Html);
    AlternateView avImages = AlternateView.CreateAlternateViewFromString(htmlBody, null, MediaTypeNames.Text.Html);

As you can see, both my views are specified as Text.Html, so the the 1st one is overriding the next one and so I only see text and images are sent as attachments

I made the following change and it worked as expected

AlternateView avText = AlternateView.CreateAlternateViewFromString(metric.Name, null, **MediaTypeNames.Text.Plain**);
AlternateView avImages = AlternateView.CreateAlternateViewFromString(htmlBody, null, MediaTypeNames.Text.Html);