ASP.NET MVC Email Template Solution
Posted On: March 1st, 2009If you are like me then you have probably ran into a wall with using ASP.NET MVC View Engine to render your awesome Dynamic HTML Email Templates. At least you put up a fight using a lot of fake data. It is actually possible to get around it!
var oldContext = HttpContext.Current;
HttpContext.Current = new HttpContext(HttpContext.Current.Request,
fakeResponse);
var html = new HtmlHelper(new ViewContext(fakeControllerContext,
new FakeView(), fakeViewDataDictionary, new TempDataDictionary()),
new ViewPage());
html.RenderPartial(viewName, viewData, viewDataDictionary);
HttpContext.Current = oldContext; //yay
Though, because you’re reading this you’re like me and you never give up! So how, how do you get around all of this? The answer is Spark. Eeek, another DLL? Yes, Spark is its own View Engine which is an entire different framework. Yes, you have to go to their website download the DLLS, put it in your Lib folder and reference it in your code. Let me tell you now, it is well worth it. Let’s dive in!
Let’s write the code to render our email using the Spark. We want our code to take in the template name, something like: “ForgotUsernameEmail.spark” and we also want it to reuse our current ViewData Object which is of type ViewDataDictionary and contains Person data, we will need to add this into our own implementation of AbstractSparkView. See samples bellow:
Render Email Method:
public string RenderEmail(string sparkViewName, ViewDataDictionary
viewData)
{
var email = new StringWriter();
var view = (EmailTemplateBase) _engine.CreateInstance(new
SparkViewDescriptor().AddTemplate(sparkViewName));
view.ViewData = viewData;
try
{
view.RenderView(email);
}
finally
{
_engine.ReleaseInstance(view);
}
return email.ToString();
}
Oops thanks Arnis, forgot to mention EmailTemplateBase is just an extended version of AbstractSparkView that includes the ASP.NET MVC ViewDataDictionary.
Custom Spark AbstractSparkView with ViewData implementation:
public abstract class EmailTemplateBase : AbstractSparkView
{
public ViewDataDictionary ViewData { get; set; }
public object Eval(string expression)
{
return ViewData.Eval(expression);
}
public string Eval(string expression, string format)
{
return ViewData.Eval(expression, format);
}
}
So that’s done, let’s make the template… In my MVC Web Project I am going to add into my Views folder or maybe even Views/Email
a file called “ForgotUsernameEmail.spark”.
Dear ${#name}:
Your username is ${#userName}.
Thank You.
I also put in a use tag to pull down a Signature file, since this is the same in everyone of my emails. Now let’s actually write the code to call it:
string email = RenderEmail("ForgotUsernameEmail.spark",ViewData);
And that’s all you need to do, well besides read up on spark syntax: http://www.sparkviewengine.com/documentation/configuring


Where does EmailTemplateBase come from?
Arnis L. (January 14th, 2010)
Sorry Arnis, I wrote this in a rush, most of the source I copied from the existing code I wrote at stackoverflow.
As you can see, if you move your mouse over _engine.CreateInstance(), it should return a type of ISparkView, I wrote an implementation of that called EmailTemplateBase using (AbstractSparkView) I added the MVC .NET ViewDataDictionary to it. Along with the Eval method triggered by the pound symbol on the view (#).
See updated post above.
Let me know if you need me to dive down into anything else.
Andrew Kharlamov (January 18th, 2010)
We also have a similar solution posted on our blog…
http://blog.deesea.com/post/New-way-to-send-fancy-template-emails-in-ASPNET-MVC.aspx
Dorian Collier (March 10th, 2010)
Awesome, thanks for sharing
Andrew Kharlamov (April 19th, 2010)
Hi Andrew,
I have a problem:
“Dynamic view compilation failed.
c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\root\e5d03160\92c61bc5b2aa4d8fa7e6a10c3c57d11c-1.cs(17,59): error CS0234: The type or namespace name ‘SparkViewBase’ does not exist in the namespace ‘Spark’ (are you missing an assembly reference?)
”
Please help!
Thanks
Suker (September 20th, 2010)
Make sure you have configured spark correctly in your project, http://sparkviewengine.com/usage/project-from-scratch#Initializingenvironmentandroutes Read the section on initializing environments and routes.
Andrew Kharlamov (September 20th, 2010)
[...] least you put up a fight using a lot of fake data. It is actually possible to get around it! var… [full post] Andrew Kharlamov CowFarm.NET developmentasp emailasp.net email templatesasp.net mvc [...]
ASP.NET MVC Email Template Solution (December 27th, 2010)