Sending an email using SMTP in .NET 4.0

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).

image

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. Smile