in Development

Embedding Images in E-Mails

Two months ago I attended to a private session at the Remix 07 where we had the opportunity to talk with some of the speakers of the event.

At a certain point one of the attendees asked to Arturo Toledo why Outlook Express was blocking images sent with html formatted mails and what was Microsoft doing to fix it. Everybody knows that probably all email clients prevent the download of images until you authorize it, this is a common sense behavior for security reasons. In any case, this guy was a bit angry because the business of his company was to create this kind of mailings and due to that, the effort of their designers was totally wasted and normally limited to insert a link to a web page with the contents of the mail.

Of course, Arturo Toledo and the rest of attendees were disconcerted, he didn’t know what to answer (we were talking about Expression products and when they would allow integration with Team Foundation Server), actually I think nobody paid too much attention to the question since the subject of the session was radically different and probably everybody prefers to download images after one click than having more SPAM (if that’s possible).

The thing is that today I remembered this question, therefore I’ve been reading a bit the MSDN to see if I could find something about it and this is what I’ve found.

It’s clear that with .NET you can send html mails very easy, basically because you only need to set an extra property: MailMessage.IsBodyHtml = true and set the MailMessage.Body property with the html you want to send. Next you can see an example about how to send an HTML mail.

   1: SmtpClient client = new SmtpClient(smtpServer, smtpPort);
   2: client.Credentials = new NetworkCredential(userName, password);
   3: client.EnableSsl = true;
   5: MailMessage message = new MailMessage(from, to);
   6: message.Subject = "Html Mail";
   7: message.Body = "<html><body><h1>test</h1><img src='http://aValidUrl/Logo.jpg'/></body></html>";
   8: message.IsBodyHtml = true;
  10: client.Send(message);

The problem with the code above is what the other guy said, the external links to images are blocked and to view them it’s necessary to click to download. To solve this we have another option: embed the images as a resources. To do it you need to work with the class AlternateView and LinkedResource. This provide us a way not only to embed the images but to create different views depending i.e. if the client supports html mails or not. If you do it in this way the images will be sent together with the mail, so it’s obvious that the size of the mail will be increased, but at least you will be able to show the images as you expected without compromise security, at least not in the same way as before. Next you can see a sample about how to do it.

   1: SmtpClient client = new SmtpClient(smtpServer, smtpPort);
   2: client.Credentials = new NetworkCredential(userName, password);
   3: client.EnableSsl = true;
   5: // Set the source of the image tag with the resource identifier
   6: string body = "<html><body><h1>Jose Fco Bonnin</h1><img src='Cid:Logo'/></body></html>";
   8: // Add the image from a local file.
   9: LinkedResource res = new LinkedResource(@"Logo.jpg", MediaTypeNames.Image.Jpeg);
  10: res.ContentId = "Logo";
  12: AlternateView htmlView = AlternateView.CreateAlternateViewFromString(body, null, MediaTypeNames.Text.Html);
  13: htmlView.LinkedResources.Add(res);
  15: MailMessage message = new MailMessage(from, to);
  16: message.Subject = "Html Mail";
  17: message.AlternateViews.Add(htmlView);
  19: client.Send(message);

I don’t know if this could be the best solution for those guys, but at least it would be a workaround.