I had need of sending embedded images within an e-mail. .NET has had a few handy classes for sending an email using SMTP for a few versions. While there were a few examples floating around the internet, none were as clean and easy to follow as I expected. So, I decided to create a simple sample application in C# which demonstrates how to embed an image (or other content) in a email that contains both plain text and HTML content. It’s really not difficult. A number of examples ignore the fact that almost all of the objects need to be disposed, so I corrected that. This code is intentionally written synchronously to keep the sample simpler and easier to follow (and I didn’t need asynchronous sending for my learning exercise).
Above is the output (if you happen to have a picture of NYC). The example code uses Gmail as the SMTP host (it has the settings that generally work for gmail in most situations, including using SSL).
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net.Mail; using System.Net; using System.Net.Mime; namespace TestEmailAttachments { public class EmailSettings { public string ToAddress { get; set; } public string FromAddress { get; set; } public string AccountName { get; set; } public string AccountPassword { get; set; } } class Program { static void Main(string[] args) { EmailSettings settings = new EmailSettings() { ToAddress = "sample@example.com", FromAddress = "sender@example.com", AccountName = "sample@example.com", AccountPassword = "mypa$$w0rd$ux" }; SendEmail(settings); Console.WriteLine("Done"); Console.ReadKey(); } static void SendEmail(EmailSettings settings) { if (settings == null) { throw new ArgumentNullException("need settings!"); } // Almost everything used my the mail system is disposable // so, we'll use 'using' liberally using (MailMessage mail = new MailMessage()) { //set the e-mail address mail.From = new MailAddress(settings.FromAddress); mail.To.Add(settings.ToAddress); //set the subject mail.Subject = "New York City!"; // create some content string textPlain = "I'm sorry, but you won't see the pretty photos inline. Look for an attachment."; string textHtml = "Here is an embedded image.<img src=cid:NewYorkCity1>"; // setup the alternate views (so different type of e-mail clients can see the content) using (AlternateView plainView = AlternateView.CreateAlternateViewFromString(textPlain, null, MediaTypeNames.Text.Plain), htmlView = AlternateView.CreateAlternateViewFromString(textHtml, null, MediaTypeNames.Text.Html) ) { //create the LinkedResource (embedded image) using (LinkedResource photo = new LinkedResource(@"D:\Temp\nyc2009\NewYorkCity (1 of 1).jpg")) { // the content id here must match the content id used in the html as the 'cid:NNNNNNNN' photo.ContentId = "NewYorkCity1"; // set the content type to match the image (in this case, it's a jpeg) photo.ContentType = new ContentType(MediaTypeNames.Image.Jpeg) { Name = "NewYorkCity (1 of 1).jpg" }; // the htmlView needs the resource htmlView.LinkedResources.Add(photo); // add each view to the alternate views collection mail.AlternateViews.Add(plainView); mail.AlternateViews.Add(htmlView); // send the message, again diposable using (SmtpClient smtp = new SmtpClient()) { // these are gmail settings... you'll need to adjust them as needed smtp.EnableSsl = true; smtp.Host = "smtp.gmail.com"; smtp.Port = 587; smtp.UseDefaultCredentials = false; smtp.Credentials = new NetworkCredential(settings.AccountName, settings.AccountPassword); smtp.Send(mail); } } } } } } }
Use this only for good.