Generating HTML emails using ASP.NET

It’s a pretty common requirement these days to send a nicely formatted email, yet I’ve come across very few “nice” solutions.

The solution I’ve come to use is simple, and documented across the web, but rarely used in the real world.

The most common code I see (and what I used to write back in the days of .NET1.0 powered dinosaurs roaming the earth) revolves around ugly use of the StringBuilder:

MailBody.Append("<html><head></head><body> \n");
MailBody.Append("<span style=\"font-size: 11 px; font-family:Verdana,Helvetica, sans-serif\">Hi,<br><br>Your account information as it has been retrieved from the database:</span><br><br> \n");
MailBody.Append("<div style=\"font-size: 11 px; font-family:Verdana,Helvetica, sans-serif\">Username: " + UserData.Username + "<br><br>" + "Password: " + UserData.Password + "</div> \n");
MailBody.Append("</body></html>");

Ugly. Unmaintainable.

Instead, create a user control for your email template using standard ASP.NET controls:

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="PasswordRecovery.ascx.cs" Inherits="SampleApp.WebUI.EmailTemplates.PasswordRecovery" %>
<h1>Password Recovery</h1>
<p>Your new password is <asp:Literal ID="NewPassword" runat="server" />.</p>

Expose a property for each value that you need to include in the email:

public string Password
{
     get { return NewPassword.Text; }
     set { NewPassword.Text = value; }
}

Now just render the control on demand:

private string RenderControl(Control control)
{
    StringBuilder stringBuilder = new StringBuilder();
    StringWriter stringWriter = new StringWriter(stringBuilder);
    HtmlTextWriter htmlTextWriter = new HtmlTextWriter(stringWriter);

    control.RenderControl(htmlTextWriter);

    return stringBuilder.ToString();
}

How simple is that. 🙂

UPDATE: I should mention how to instantiate the control – just calling the default constructor isn’t good enough as you’ll find that all of your controls are null. This is the magic line you’ll need:

EmailTemplates.MembershipApplication emailTemplate = (EmailTemplates.MembershipApplication)LoadControl("~/EmailTemplates/MembershipApplication.ascx"); 

8 comments

  1. Hi Tatham,

    I’ve been looking for a better way to render HTML emails than manual stringbuilder work. As you say, its ugly and unmanageable if the HTMl is significant.

    I’ve tried implementing this code but I’m having trouble. First I can’t seem to place the rendercontrol function within a code behind file. It complains it shadows an overridable methiod in the base class ‘Control’. Second I’m using VB! Yeah I know, I used to be a C+ developer but had to switch with my work, so been using it no for long time and its fairly productive.

    Anyway, that aside, I’d really appreciate it if you could provide a complete example of the coding and maybe a sample usercontrol its applied to. I’ll then be able to convert to my native coding language.

    Any help much appreciated.
    Steve

  2. OK putting the rendercontrol in a public class file has solved point1. So now I’m stuck on instantiating the control and setting all the literals in the template.

  3. Finally managed to get everything working. Thanks for the pointers in the first place. I’m now generating very nice emails.

  4. Thx I really appreciate your example, I’m having some difficulties though.

    Maybe I’m not as clever as the average bear, but:

    1) Where should the .ascx file be located?
    2) The “RenderControl(Control control)” method, where is this suppose to go? Obviously not in the .ascx.cs file..
    3) Instantiating or initializing the control, you have “EmailTemplates.MembershipApplication”. Is this your own class or is this a built in .net class?

  5. Ah, just re-read Steve’s comment, so the RenderControl method goes in a public class, completely separate from the .ascx file, still working on the rest though.

  6. Hi, I want to say I have been using this pattern for years and it is very successful. I use ASPX, not ascx, and then I use httpwebquest to crawl the contents of that ASPX page..

    Advantages
    1. We can use repeater or datagrid in that ASPX or ASCX
    2. HTML CSS is very strict, we can change design
    3. We can have a master page for email header and footer, because header and footer are replicated contents in most emails
    4 We can truly seperate the presentation layer

  7. Thanks for taking this opportunity to talk about “Generating HTML emails using ASP.NET « Tatham Oddie”, I benefit from learning about this topic. If possible, as you gain data, please update this blog with new information. Thanks, Hier

Comments are closed.