Smarter email templates in ASP.NET with RazorEngine

By March 31, 2014 ASP.NET No Comments

Every web application I work on has a requirement on sending emails to their users upon completing some action. Be it be an order placed email, comments added to a blog email or any other workflow that assures the user that he completed a workflow that is designed by the site.

Most of these emails are more than just a “status update” meaning these emails would have lot of relevant information to the user. For example if you take a email that the user receives when he places an order with an eCommerce website, the user would except to see emails which would involve information about his order, his shipping address, his order number, and what he was charged etc.

Traditionally lot of these email templates were developed a big blob of string with placeholders in them for replacing the information that needs to be in the email. This approach although works, isn’t clean as you, a developer, wouldn’t want to see a huge blob of string with placeholder in it when you wan to fix an issue with the template. Another thing to consider is having inline styles (to make the email look pretty) would further worsen the case of having a huge blob of string template.

Enter, RazorEngine

If you are like me, and love Microsoft’s Razor syntax you will love RazorEngine. Razor engine is a templating engine that is built up on Microsofts Razor syntax. RazorEngine has a Nuget package that you can use to bring the library to your project easily. The latest version of RazorEngine is built for .NET Framework 4.5 but if you are still working with an application that has not been upgraded to .NET 4.5 you can get an older version of RazorEngine that support .NET 4.0

 

Why are email templates with RazorEngine smarter?

what makes RazorEngine smarter is the ability to have model binding and templates among many more.

Lets continue the scenario of a user receiving an email for an order he placed. Now lets create a “HTML Template” that will serve as the email template that the user will receive.

Html_Templates_Folder

The contents of the HTML file would look like below

@model SmarterEmails.ViewModels.OrderViewModel
<h1>Order Placed Email Notification</h1>
<
p>@Model.SiteUrl</p> 

Dear @Model.CustomerName, 

<h2>Thank you.</h2>
<
p>
You’ve made a purchase on <a href=”@Model.SiteUrl”>@Model.SiteName</a>
</
p><

div>
<
strong>Order number:</strong> @Model.OrderNumber
</div>
<
div>
<
strong>Order date: </strong> @Model.OrderDate
</div><

table>
<
thead>
<
tr>
<
th>
Item
</th>
<
th>
Price
</th>
</
tr>
</
thead>
<
tbody>
@foreach(var product in Model.Products){
<tr>
<
td>
@product.ProductName
</td>
<
td>
@product.Price
</td>
</
tr>
}
</tbody>
</
table><

p>
If you have any questions on the order, please contact <a href=”@Model.SiteUrl”>@Model.SiteName</a>
</
p><

p>
Thank you for your business,
</p><

strong>@Model.SiteName</strong>

You can see that I have a Model “OrderViewModel” bound to this template there by having clean syntax on the properties. and the template is a HTML file which makes it really easy to read. Below is how the OrderViewModel would look like

using System.Collections.Generic; 

namespace SmarterEmails.ViewModels
{
public class OrderViewModel
{
public string OrderNumber { get; set; }
public string OrderDate { get; set; }
public string CustomerName { get; set; }
public List<ProductViewModel> Products { get; set; }
public string ShipToAddress { get; set; }
public string SiteUrl { get; set; }
public string SiteName { get; set; }
}
}

And ProductViewModel

namespace SmarterEmails.ViewModels
{
public class ProductViewModel
{
public string ProductName { get; set; }
public string Price { get; set; }
}
}

Now, all we have to do is construct the ViewModel and run it by RazorEngine parsing logic.

var fromEmailAddress = “venkata@falafel.com”;
var toEmailAddress = “user@site.com”;
var subject = “Your Falafel Store Order”;
var template = File.ReadAllText(HttpContext.Current.Server.MapPath(“~/Templates/OrderPlaced.html”)); 

//Dummy data
var viewModel = new OrderViewModel
{
SiteUrl = GetSiteUrl(),
SiteName =
“Falafel Store”,
CustomerName =
“Venkata Koppaka”,
OrderNumber =
“2372″,
OrderDate =
DateTime.Now.ToString(“MMM dd, yyyy h:m:s tt”),
Products = GetProducts(
“2372″),
ShipToAddress =
“123 Some Avenue, Some City, Some State, 12345″
};
var body = Razor.Parse(template, viewModel); 

EmailSender.Send(fromEmailAddress, toEmailAddress, subject, body);

Once you run this code, you will get a nice looking email like below -

RazorEngine_Email

Hope this helps,

Venkata

The following two tabs change content below.

Venkata Koppaka

Senior Software Engineer at Falafel Software
Venkata Koppaka has over 7 years experience developing variety of line of business applications to various financial and IT organizations. Venkata has been developing with all Telerik products since 2008, he ended working for Telerik on Sitefinity team as a senior developer for Ecommerce module. He is extremely interested in developing custom solutions for Sitefinity based Ecommerce stores. Venkata is a big fan of Test Driven Development and strives himself to write code that is completely testable and modular. Venkata has a Masters in Computer Science from Syracuse University, which drives his continuos learning addiction. In his spare time, Venkata develops apps for Windows Phone 8 platform and learns the most cutting edge technologies in software development. When he is not spending time on computer writing software, Venkata enjoys reading about cars and watching football.