C#, ASP .Net, JavaScript, SQL Server, and some more

Menu

Using XSLT as email template engine in C#

Email has been (and will be for some time) one of the main means to communicate with your customers and perform various core business and security tasks (such as confirming a newly created accounts, helping a user reset their lost password, notify updates and required actions, etc.). These emails usually consist of static sections and some dynamic parts that are specific to the user receiving the email.

Sometimes, a simple string replacement approach works to achieve such goal (that’s what I used to do before). But if you need something more elegant and powerful than that, a good option would be using XSLT. I am no XSLT expert and I won’t talk about it in this post, but I encourage you to learn about it if you don’t already know. In order to follow the principle of separation of concerns and improve testability, the solution is separated into four components with their corresponding interface (contract):

An email sender (IEmailSender). Another wrapper, in this case, around the SmtpClient. This is abstracted away in order to mock the actual sending of the email when testing (dump the result to console or to a text file, etc.).

A custom XML serializer (IXmlSerializer). Why not use the built in XML serializer? Simple: it doesn’t work with anonymous objects. Sometimes we want to pass our variables without having to explicitly create a class for it. In case you do want to use the regular serializer, you can always create a wrapper that implements IXmlSerializer.

The XSLT compiler

Not much to say about it. It will accept an input XML stream (this would be your variables object serialized as XML), an XSLT file path (or stream), and an output stream to dump the resulting transformation. If you use the overload that accepts the XSLT file path, the XslCompiledTransform object will be cached.

The email sender

Again, as simple as it sounds. Just to decouple the actual sending of the email. In the example, I dump the result to an HTML file called output.html.

The XML Serializer

For the custom XML serializer, I borrowed Martin Normark‘s solution, but made some modifications to it, mainly allowing for the serialization of any kind enumerable, not only arrays.

Basically, it will turn any object into XML following these rules:

If no root element name is provided, “object” will be used.

All properties will be serialized as XML nodes with the same name as the property.

For collection properties, the main node will be named after the property, and the child nodes will have the same name with the suffix “Item” appended.

The template email sender

This is the one that puts all together, and has dependencies to everything else. It only has a Send method (and its async counterpart). You’ll notice that it does not accept a from parameter. That’s because you usually handle that in the SMTP configuration part of your project’s web.config or app.config. If you need it, just go ahead and add it.

Additionally, this service has a LayoutFilePath property. Inspired by ASP .NET’s layout (or master) pages, only much simpler, this allows to have a base, static HTML content file where you can put the frame and layout that is common to all the emails that you will send. If this property is null, then the output will be only what results from the XSLT transformation. The only requirement for your layout file is that you need to include the following wherever you want the content placed: