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;
   4:  
   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;
   9:  
  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;
   4:  
   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>";
   7:  
   8: // Add the image from a local file.
   9: LinkedResource res = new LinkedResource(@"Logo.jpg", MediaTypeNames.Image.Jpeg);
  10: res.ContentId = "Logo";
  11:  
  12: AlternateView htmlView = AlternateView.CreateAlternateViewFromString(body, null, MediaTypeNames.Text.Html);
  13: htmlView.LinkedResources.Add(res);
  14:  
  15: MailMessage message = new MailMessage(from, to);
  16: message.Subject = "Html Mail";
  17: message.AlternateViews.Add(htmlView);
  18:  
  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.

E-Mail Alerts

I'm sure that all of us first or later needed to write a piece of code that sends alerts by e-mail, it doesn't matter if it was a very complex notification system or if we just wrote a few lines to do it, but probably all of us did it. If people use Outlook, there is a very simple trick to stand out the e-mails you send and impress some end-users.

The only thing you need to do is to add a header to the instance of the MailMessage class and Outlook will show the mails with a bell icon instead of the standard envelope icon. Let's see how to do it exactly.

   1: System.Web.Mail.MailMessage message = new System.Web.Mail.MailMessage(); 
   2:  
   3: message.From = "xxx"
   4: message.To = "xxx"
   5: message.Subject = "xxx"
   6: message.Body = "xxxx" 
   7:  
   8: message.Headers.Add("message-id", "<3BD50098E401463AA228377848493927-1>"); 
   9:  
  10: System.Web.Mail.SmtpMail.SmtpServer = "localhost"
  11: System.Web.Mail.SmtpMail.Send(message); 

The header we add is a formatted string with a fixed Guid and the real message id, in this case 1. The Guid "3BD50098E401463AA228377848493927" is what does the trick.

This happens because Outlook and actually any application compatible with Sharepoint Services thinks that the message received is an alert coming from Sharepoint Services so it identifies them in showing a bell as the message icon.

I just talk about this as a funny thing in order your notification applications seem more sophisticated, but there are some interesting concepts behind it. Maybe you want to take a look to the SMTP Headers/X-Headers and the extensibility of the Sharepoint Services.

PS: Happy New Year!!!!