It doesn’t take much to hack together email functionality using the .NET framework.  In most cases you can new-up a MailMessage reference, assign sender and recipient addresses, provide a subject and a message body, configure your SMTP settings and then send.  Done and done.

But let’s say you need to provide both plain text and HTML versions of your message body.  Or maybe you would like to embed an image or two within the message body.  Or, what if, for some reason, you actually want to handle exceptions appropriately.  Well, there’s more to it then.

There are a numerous ways to better organize the following code.  In fact, we just went through an exercise at work where we refactored the heck out of the core email functionality and produce a really clean usable component which can be easily mocked, configured and leverages email templates.  It’s pretty cool.  That being said, I believe the following sample demonstrates the aforementioned core features of .NET emailing. 

I hope it helps. Let me know if I missed anything or it the example could be more clear.

try
{
    // Assign a sender, recipient and subject to new mail message
    MailAddress sender =
        new MailAddress("sender@johnnycoder.com", "Sender");

    MailAddress recipient =
        new MailAddress("recipient@johnnycoder.com", "Recipient");

    MailMessage m = new MailMessage(sender, recipient);
    m.Subject = "Test Message";

    // Define the plain text alternate view and add to message
    string plainTextBody =
        "You must use an email client that supports HTML messages";

    AlternateView plainTextView =
        AlternateView.CreateAlternateViewFromString(
            plainTextBody, null, MediaTypeNames.Text.Plain);

    m.AlternateViews.Add(plainTextView);

    // Define the html alternate view with embedded image and
    // add to message. To reference images attached as linked
    // resources from your HTML message body, use "cid:contentID"
    // in the <img> tag...
    string htmlBody =
        "<html><body><h1>Picture</h1><br>" +
        "<img src=\"cid:SampleImage\"></body></html>";

    AlternateView htmlView =
        AlternateView.CreateAlternateViewFromString(
            htmlBody, null, MediaTypeNames.Text.Html);

    // ...and then define the actual LinkedResource matching the
    // ContentID property as found in the image tag. In this case,
    // the HTML message includes the tag
    // <img src=\"cid:SampleImage\"> and the following
    // LinkedResource.ContentId is set to "SampleImage"
    LinkedResource sampleImage =
        new LinkedResource("sample.jpg",
            MediaTypeNames.Image.Jpeg);
    sampleImage.ContentId = "SampleImage";

    htmlView.LinkedResources.Add(sampleImage);

    m.AlternateViews.Add(htmlView);

    // Finally, configure smtp or alternatively use the
    // system.net mailSettings
    SmtpClient smtp = new SmtpClient
          {
              Host = "smtp.bigcompany.com",
              UseDefaultCredentials = false,
              Credentials =
                  new NetworkCredential("username", "password")
          };

    //<system.net>
    //    <mailSettings>
    //        <smtp deliveryMethod="Network">
    //            <network host="smtp.bigcompany.com"
    //              port="25" defaultCredentials="true"/>
    //        </smtp>
    //    </mailSettings>
    //</system.net>

    smtp.Send(m);
}
catch (ArgumentException)
{
    throw new
        ArgumentException("Undefined sender and/or recipient.");
}
catch (FormatException)
{
    throw new
        FormatException("Invalid sender and/or recipient.");
}
catch (InvalidOperationException)
{
    throw new
        InvalidOperationException("Undefined SMTP server.");
}
catch (SmtpFailedRecipientException)
{
    throw new SmtpFailedRecipientException(
        "The mail server says that there is no mailbox for recipient");
}
catch (SmtpException ex)
{
    // Invalid hostnames result in a WebException InnerException that
    // provides a more descriptive error, so get the base exception
    Exception inner = ex.GetBaseException();
    throw new SmtpException("Could not send message: " + inner.Message);
}

8 Comments to “.NET MailMessage, LinkedResources, AlternateViews and Exceptions”

  1. Pankaj says:

    Dear SIr,

    Kindly Let me know what to pass in content Id in case if i am sending multiple image from database. I tried so many times but it always show the last image of my database in each image. Kindly email me if you have any suggestions.

    i ll wait for your reply.

    regards
    PANKAJ

  2. Ben Griswold says:

    @Pankaj – You have full control of the contentids. You may include multiple images in htmlBody just makes sure that each image’s contentid is unique. I hope this helps.

  3. Ramesh Rana says:

    Dear Sir,

    Kindly Let me know how to pass multiple images path in (LinkedResource sampleImage =
    new LinkedResource(“sample.jpg”,MediaTypeNames.Image.Jpeg)). If all of my images are stored in a web server.
    if i am using my web server path e.g (http://www.dareadventures.com/folder/IMAGE_NAME) then i m getting a error (URI Formats are not supported). Because LinkedResourse searching the image in local drive e.g. (C:\document and setting……..), But my images are on the web server. So kindly email me if you have any suggestions, how to pass the web server path in LinkedResource.

    I’ll wait for your reply.

    Thanks & regards,
    Ramesh Rana

  4. I like this place very much.

    This is really a outstanding website.
    And it is not like other money orientated site, the info here is really useful.

    I am definitely bookmarking it as well as sharin it with my friends.

    :)

  5. Willy says:

    Hi Ben,

    I am having the same issue that Ramesh Rana posted on August 24, 2009. I get the image as an attachment instead of embedded in my html design, in spite of having the src tag properly located.

    Also I have my images in a web server so my paths are all like “http://mywebsite.com/myimages/image.jpg” and when I use this instead of the internal path (c:/myimages/image.jpg) I get the same error.

    Could you please post the answer I guess you already provided to Ramesh?

    Thanks

  6. [...] johnnycoder.com/blog/2009/04/15/ This entry was written by enterprisemind, posted on March 29, 2010 at 2:16 pm, filed under Uncategorized. Bookmark the permalink. Follow any comments here with the RSS feed for this post. Post a comment or leave a trackback: Trackback URL. « Twitter API and C# [...]

  7. kadir avci says:

    Thanks. This is very useful for me.

  8. Ben Griswold says:

    Hi Kadir, I’m very happy to help. Best of luck.

Leave a Reply

You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>