code.nontalk.com

Code snippets for C#, T-SQL and JavaScript

Friday, December 19, 2008

Simple Html Email Template Class

I very often have to send HTML formatted email addresses from a web application. I have taken many approaches when building the HTML message. Lately I have been using html files as templates which have replaceable "tokens". Then I read the file into a string then do a series of replace statements like so:

string name = "Jesse";
string city = "Minneapolis";

string body = FileHelper.Read("~/templates/email.htm");
body = body.Replace("{Name}", name);
body = body.Replace("{City}", city);

[...send email...]

After noticing how many times I have done this same thing, I decided to build a simple class to make this easier. My new code looks like this.

string name = "Jesse";
string city = "Minneapolis";

Template t = new Template("~/templates/email.htm");
t.Tokens.Add("{Name}", name);
t.Tokens.Add("{City}", city);
string body = t.Replace();

[...send email...]

It's actually more lines of code but it 'feels' cleaner to me. Here's the class.

using System;
using System.Collections.Generic;

public class Template
{
    public string Contents { get; set; }
    public Dictionary Tokens { get; set; }

    public Template() {}

    public Template(string filename)
    {
        this.Tokens = new Dictionary();
        this.Contents = FileHelper.Read(filename);
    }

    public Template(string contents, Dictionary tokens)
    {
        this.Contents = contents;
        this.Tokens = tokens;
    }

 public string Replace()
 {
        foreach (KeyValuePair item in this.Tokens)
        {
            this.Contents = this.Contents.Replace(item.Key, item.Value);
        }
        return this.Contents;
 }

    public static string GetReplacedFile(string filename, Dictionary tokens)
    {
        Template t = new Template(filename);
        t.Tokens = tokens;
        return t.Replace();
    }

    public static string ReplaceTokens(string contents, Dictionary tokens)
    {
        Template t = new Template(contents, tokens);
        return t.Replace();
    }
}

Here's the FileHelper class that I use.

using System;
using System.Configuration;
using System.Drawing;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;

/// 
/// Provides utility methods for working with files.
/// 
public class FileHelper
{

 public static String ImageExtPattern
 {
  get { return @"png|jpg|jpeg|gif|tiff|tif"; }
 }

 public static string Read(String filename)
 {
  if (!Path.IsPathRooted(filename))
  {
   filename = System.Web.HttpContext.Current.Server.MapPath(filename);
  }
  return ReadFromDisk(filename);
 }

 private static string ReadFromDisk(String filename)
 {
  StringBuilder sb = new StringBuilder();
  StreamReader sr = File.OpenText(filename);
  String str = sr.ReadLine();

  while (str != null)
  {
   sb.Append(str + "\n");
   str = sr.ReadLine();
  }

  sr.Close();
  return sb.ToString();
 }

 public static void SaveFile(String directory, String filename, System.Web.HttpPostedFile file)
 {
  if (!Path.IsPathRooted(directory))
  {
   directory = HttpContext.Current.Server.MapPath(directory);
  }

  if (!Directory.Exists(directory))
  {
   Directory.CreateDirectory(directory);
  }

  String path = Path.Combine(directory, filename);

  file.SaveAs(path);
  file.InputStream.Close();
 }

 public static void DeleteFile(String path, String name)
 {
        if (string.IsNullOrEmpty(name)) return;
        string filePath = Path.Combine(path, name);
        DeleteFile(path);
 }

 public static void DeleteFile(String path)
 {
        if (string.IsNullOrEmpty(path)) return;
        if (!Path.IsPathRooted(path)) path = HttpContext.Current.Server.MapPath(path);
  if (File.Exists(path)) File.Delete(path);
 }


    public static Boolean Exists(String path, String name)
    {
        if (string.IsNullOrEmpty(name)) return false;
        string filePath = Path.Combine(path, name);
        return Exists(filePath);
    }

    public static Boolean Exists(String path)
 {
        if (string.IsNullOrEmpty(path)) return false;
        if (!Path.IsPathRooted(path)) path = HttpContext.Current.Server.MapPath(path);
  return File.Exists(path);
 }
}

Labels: