User Control Email Templates in asp.net

Just about every project i work on needs to send customized emails and everytime I hate doing it. Inspired by some answers in this stackoverflow question I thought I’d give a simple .ascx based email template system a dig.

First thing I did was set up a base class for template controls to inherit from. This class inherits from UserControl and has the methods to render the control to a string. It also has methods and properties to set up “tags” to replace in the email body.

/// <summary>
/// Base class for user control to inherit so it can be used as an email template
/// </summary>
public class EmailTemplateBase : UserControl
{
    public EmailTemplateBase()
    {
        Tags = new Dictionary<string, string>();
    }

    public Dictionary<string, string> Tags { get; set; }

    protected string GetTagValue(string tagName)
    {
        return Tags[tagName].Value;
    }

    protected string GetTagValue(string tagName, string defaultValue)
    {
        string val = GetTagValue(tagName);
        return string.IsNullOrEmpty(val) ? defaultValue : val;
    }

    public string RenderTemplate()
    {
        StringBuilder sb = new StringBuilder();
        StringWriter sw = new StringWriter(sb);
        Html32TextWriter htw = new Html32TextWriter(sw);
        RenderControl(htw);

        // Get full body text
        return sb.ToString();
    }
}

Below is a simple example from the project I am working on it is used for sending feedback emailsĀ  This template is really simple but because the rendering uses the same page cycle as a regular control you can style and render the template how ever you like.

<%@ Control Language="C#" ClassName="Feedback" Inherits="Common.Email.EmailTemplateBase" %>
<p>
   Feedback from System sent <%= GetTagValue("sent")%>
</p>

<p>
    <strong>Sender: </strong> <%= GetTagValue("sender")%><br />
    <strong>Subject: </strong> <%= GetTagValue("subject")%>
</p>

<p>
    <strong>Message: </strong> <br />
     <%= GetTagValue("message").Replace(Environment.NewLine, "<br />")%>
</p>

I created a class to easily load and use the email templates within my code by passing the location of the template on the server.

/// <summary>
/// Uses a .ascx file as an email template
/// </summary>
public class EmailTemplate
{
    private readonly EmailTemplateBase _template;

    public EmailTemplate(string templateLocation)
    {
        Page p = new Page();
        _template = (EmailTemplateBase) p.LoadControl(templateLocation);
    }

    public Dictionary<string, string> Tags
    {
        get { return _template.Tags; }
        set { _template.Tags = value; }
    }

    public string Render()
    {
        return _template.RenderTemplate();
    }
}

Below is how I use the templates in my code, sending using a basic email sender class I have (or better still fluent email).

var template = new Common.Email.EmailTemplate("~/Emails/Templates/Feedback.ascx");
template.Tags.Add("sender", sender);
template.Tags.Add("sent", sent);
template.Tags.Add("subject", subject);
template.Tags.Add("message", message);

string body = template.Render();

EmailSender.Send(from, fromName, to, toName, subject, body);

I could probably try encapsulate a bit more of the email sending inside my template (toName, toAddress etc) to clean this up a bit so feel free to tell me how come I suck.

9 Responses

  1. Pingback: DotNetShoutout

  2. Wyvern says:

    Tags.Where(t => t.Key == tagName).SingleOrDefault().Value;
    Why not using return Tags[tagName] directly

  3. Haha good point Wyvern. I probably wrote this too early in the morning/too late at night

  4. Thanks Doug. Yeah I took a look at your post, that technique works pretty well from returning control/page html for ajax funtions.

  5. Pingback: Simple C# Synchronous / Asynchronous Email Sender | lukencode

  6. Graciela says:

    Hi. I’m new on ASP.NET and I’m trying to learn how to send an email using an .ascx page as template. Following the code above, I’m lost where each piece of code is located.
    My assumption is:
    The first block of code is the code behind the control, is the file EmailTemplate.ascx.cs.
    The second block is the control EmailTemplate.ascx.
    The third block is a separate file EmailTemplate.cs? Or is part of the code behind on other page?
    The last part: is the code behind the page that will send the email?
    I will really appreciate if you can clarify a little this.
    Thanks in advance.

  7. Luke! Just wanted to say thanks for this. Very clean, saved me at least an hour. Much appreciated.

  8. Tim Hansen says:

    Hey, I was wondering if you could elaborate on what the file structure would be like for this project? What type of file would you put each piece of code in? Like, “I put this in the code behind”, “this is in EmailTemplate.ascx”, etc?

    Thanks

Leave a Reply

Your email address will not be published. Required fields are marked *

*

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