Generate HTML e-mail body in C# using templates

Almost a year ago, I answered a question on StackOverflow, about if there’s a better way to generate HTML e-mails in C# than using a StringBuilder and just appending strings one by one.

I think that any modern piece of software today, needs to send e-mail. Whether it being password recovery e-mails, rich reports, newsletters or anything else – being able to easily see and customize the look and feel of your e-mails is vital.

So, the worst way I could think of is having your HTML hidden away in some StringBuilder.Append() hell. The best solution (in my opinion) would be, if you could have plain old HTML files with parameters like <#FirstName#> so you could dynamically replace those at runtime.

The MailDefinition class

Luckily, there’s a class for that! If you read the comments on my answer on StackOverflow, you’ll notice that none of them was familiar with that class and it came as a bit of a surprise. It did for me too, I actually wrote my own “MailDefinition” class that did just about the same thing. A complete waste of time, and it only tells me that us, developers, are sometimes too trigger happy on the keyboard instead of doing some research first. A quick search in the MSDN documentation would have saved me some work here and there.

Using the MailDefinition class is pretty straight forward. You use the MailDefinition class to create an instance of MailMessage, which you can send straightaway:

MailDefinition md = new MailDefinition();
md.From = "";
md.IsBodyHtml = true;
md.Subject = "Test of MailDefinition";

ListDictionary replacements = new ListDictionary();
replacements.Add("<%Name%>", "Martin");
replacements.Add("<%Country%>", "Denmark");

string body = "
Hello <%Name%>

You're from <%Country%>.
"; MailMessage msg = md.CreateMailMessage("", replacements, body, new System.Web.UI.Control());

Instead of having the HTML inside the code, you could easily have it in your database or as a file on the computer. That will also enable you to edit the look and feel of the HTML template at any time, without having to rebuild and deploy your application.

MailDefinition is located in the System.Web assembly, so don’t forget to add reference to that from your project.

  • Pingback: How to Send HTML E-mail from an ASP.NET MVC Controller | Martin Normark's blog

  • bri

    Bad choice of <% tags above. I had to view the source to see what you meant in your code snippet.

  • Martin H. Normark

    It doesn’t seem to mess things up in my browser, but I do have problems with code formatting occasionally – I’m thinking about hosting code snippets using Github.

  • Geiger

    Why not just use string.format?

    string body =  Server.HtmlEncode(string.Format(@”Hello {0}


    You’re from {1}.






  • Martin H. Normark

    You could easily do that. But then you lose the ability to have HTML templates with named replacement-tokens – which is kind of the point. Editing the templates would be very hard, if all tokens were {0}…{n}, and there were quite a few of them.

    Much easier to see what each parameter is with the tokens.

  • Paul King

    That is awesome. Thank you so much.

  • Avinash

    I’m curious to Know how to Insert the HTML content from a file.
    I mean , I have the HTML file in the system, I just need to insert this as body

  • Martin H. Normark

    This is how you read the body from a file on disk:

  • JM

    Thanks Martin! This blog helped me a lot! =)

  • Jeffclark

    I am interested in this article.  I have looked to send HTML through email on the web and only found stringbuilder solutions.  What I want to find out is if I have an HTML document on disk and I want to read that into the body of my email and then replacing information into original HTML file in the email.  So not to confuse you.  I have an HTML form that I want to populate and email from my website.  Can you direct me on how to go about this?

  • Martin H. Normark


    Look at this for reading files from disk:

    And this for writing the output back to disk:

    After calling CreateMailMessage you should be able to get the body, by reading the Body property on the MailMessage returned.

  • Федя Михайлович Сумкин

    MailDefinition is actually a strange class, which uses ViewState to save property velues. And it forces you to create an instance of new System.Web.UI.Control(), what I don’t like to do. The only usefull thing it does – it appends an “AlternateView” to msg.AlternateViews:
    AlternateView alternateView = AlternateView.CreateAlternateViewFromString(body, null, “text/html”);
    this peace of code is what you actually need. Well, this ist true for me, but if you really want to read a file from disk each time before sending an e-mail, using MailDefinition class may be fine.

  • Martin H. Normark


    You don’t have to read the content from disk. In my example I pass in the body via a string: MailMessage msg = md.CreateMailMessage(“”, replacements, body, new System.Web.UI.Control());

  • lbytesxk

    Does this only work with web based emails or can I use it with System.Net.Mail class? (need to send HTML email via exchange server)

  • Martin H. Normark

    It does work with System.Net.Mail — when you call CreateMailMessage on the MailDefinition, it returns an instance of System.Net.Mail.MailMessage for you to sent:

  • Thando Khumalo

    Great staff!! It works even if you use the MailMessage(): System.Net.Mail class. I was missing the message.IsBodyHtml = true par, thanks Martin

  • Martin H. Normark

    You’re welcome!

    Glad you liked it.

    / Martin

    Sent from Mailbox for iPhone

  • Pingback: Generating HTML email body in C# - C# Solution - Developers Q & A

  • Ben Powell

    This looked so promising, but I find it sad that this class is so tightly bound to System.Web.

    Often you want to send email from applications other than a website, or the business logic is buried outside the website in an enterprise solution and you don’t want to add a reference to System .Web from your business logic (often you can’t since you’d create a circular reference).

    Looks like an opportunity to build something similar without this dependency.

  • Martin H. Normark

    Hi Ben

    I’ve actually moved entirely away from this approach, and instead I use MvcMailer for rendering/generating HTML e-mails.

    Regarding business logic, I’ve added a dedicated MailController to my MVC project that provides a set of action that can be called via simple HTTP GET/POST request from other backend services etc. so I always have e-mail templates in the same place, and they’re always sent from the same place as well.

  • Pingback: [RESOLVED]Email a page | ASP Questions & Answers

  • Pingback: [RESOLVED]Email a page | ASP Web Form Data Control

  • Pingback: [RESOLVED]Email a page | ASP.NET MVC

  • Rajmohan G

    This really useful. Can I pass array value to template and use it?

  • Martin H. Normark

    For more complex models, you’ll be better off using something like MvcMailer:

    Then you can create a view, just as if it was a view for any controller action and you can iterate through the items in the array.

  • Axel Zarate

    I used a similar approach once. Now I use XSLT to process my e-mail templates. It has built-in framework support and it’s not tied to ASP.Net. Part of the solution is inspired in one of Martin’s articles. You can check it out here

  • nope

    You do realise sending an email is a WEB operation 99% of the time right?

  • Ben Powell

    Go take a look at System.Web again:

    There is a good reason why we have System.Web and System.Net.Mail. Mail notably isn’t handled in System.Web.Mail for a good reason. System.Web contains a load of classes aimed at dealing with HTTP requests and responses, Sitemaps and a couple of utility methods. Last time I looked, Mail didn’t go over HTTP.

    Large applications often aren’t just web based. Whilst one part might be a web front end, there might be a Windows Forms or WPF backend. Maybe some Windows Services that run a message bus that need to process messages out to end users.

    You don’t have this problem in small websites where the website is the entire app, but enterprise applications do need more than just a website. That’s why you don’t want to have a reference to System.Web in a Windows Service running NServiceBus (for example).

  • Martin H. Normark

    The more sophisticated your mail needs are, the more difficult it gets to do this without relying on a web stack. It’s quite cumbersome to build e-mails “by hand”, even using MailDefinition. There are some great open source libraries such as MvcMailer and ActionMailer.Net – but they rely even more on the web stack.

    I’ve found the best way for this to be to provide mail capability via an ASP.NET MVC web app using MvcMailer or ActionMailer.Net, and then having a controller that other apps can hit when they want to send an e-mail. So you sort of make your own e-mail API other apps can hit.