Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Announcing MvcMailer - Send Emails Using ASP.NET MVC View

0.00/5 (No votes)
28 Jan 2011 1  
MvcMailer NuGet package allows you to render MVC View as Email Body

The Problem

Did you ever have to send a professional looking HTML email from your ASP.NET MVC APP? Say, to welcome a newly signed up user or to send a password reset link? I am sure at some point you had to! Well, at some point, we all have to send out emails from our app, be it for the sake of a notification or the "tell a friend" feature or anything... the sad part is, constructing HTML emails with personalized text, images and styles is at least a pain in the neck (or somewhere else for that matter)! To visualize, this is how it often looks in the code:

StringBuilder mailBody = new StringBuilder();
mailBody.Append("<html><head><style type=\"text\css\">...</style></head>");
mailBody.Append("<body>")
mailBody.AppendFormat("Hi {0}<br/>", user.FirstName);
...
... XX lines of similar Appending unless it its done!
...	
mailBody.Append("</body></html>");

A Desired Solution

Wait a minute! We are already creating complex HTML views with all the styling, master paging and dynamic content from our MVC view files. This is exactly what we need in the HTML emails! So, to me, a desired solution will be like the following:

/* Layout: ~Views/Notifier/_Layout.cshtml */
<html>
	<head>
		<style type="text\css">
			...
		</style>
	</head>
<body>
	<div class="banner"></div>
	<div class="mailBody">
		Hello @user.FirstName:<br/>
		@RenderBody()

		Thank you.
		--
		The Team!
	</div>
<body>
</html>

/* WecomeMessage: ~Views/Notifier/WelcomeMessage.cshtml */
Welcome to the Team Site. Please click the following link to complete your account signup! 

@Html.ActivationLink(user.ActivationUrl)

Isn't this cleaner?

Introducing MvcMailer NuGet package

MvcMailer is available here. To install this, just open up your Package Manager Console and run "Install-Package MvcMailer" (without the quotes) and you are done! If you are new to NuGet, I would recommend you to install it to utilize free libraries out there as a plugin to your app just like MvcMailer!

Using MvcMailer

Once you install MvcMailer NuGet package, it adds the following to your project:

  1. A reference to Mvc.Mailer.dll
  2. Notifier.cs to Mailers
  3. _Layout.cshtml and WelcomeMessage.cshtml to Views/Notifier
  4. system.net mailSettings to web.config

If you open Mailers/Notifier.cs, you will find an example of how to send emails using the MvcMailer library. You can follow this list to get up and running in 3 minutes:

  1. Open up web.config and replace the placeholders with appropriate values for the following section:
    <smtp from="some-email@gmail.com">
    	<network enableSsl="true" host="smtp.gmail.com" 
    	port="587" userName="some-email@gmail.com" password="valid-password"/>
    </smtp>									
  2. Open Mailers/Notifier.cs and replace the recipient with an appropriate email address:
    mailMessage.To.Add("some-email@gmail.com");
  3. Now, add the following code to send an email in your controller, model or anywhere else:
    using Mvc.Mailer;
    using YourAppRootNamespace.Mailers;
    ...
    new Notifier().WelcomeMessage().Send();
    ...				 

    You can also send asynchronous email by using the following:

    new Notifier().WelcomeMessage().SendAsync();

So, all in all, just 1 line of code on top of its 2 lines of standard .NET Mail configuration to send email utilizing the power of all MVC Views! Sounds good, huh?

How Does This Work?

If you look in the WelcomeMessage() method inside Mailers/Notifier.cs, you will see this line:

mailMessage.Body = PopulateBody(mailMessage: mailMessage, 
                               viewName: "WelcomeMessage")

The above line populates the mailMessage.body with the string containing the compiled HTML from the view as it would be in the case of a regular MVC view! So, you get full power of your view engine to build the email body instead of the ugly looking string concats all over the place!

As you can see, it uses the same view engine as your rest of the views do. So, it just reuses the components from the existing ASP.NET MVC framework and extends on top of it. It extends the ViewResult class of ASP.NET MVC with a new class called StringResult. StringResult does exactly what ViewResult does with one exception: instead of writing to the HTTP Response Output Stream, it simply writes to a StringBuilder! So, the HTML generation is exactly the same, but the rendering is different.

Now that the view, along with its master pages and dynamic contents are compiled into a string, it can be used as the email's body. This is how it works. Apart from this, it leverages the standard MailMessage class of System.Net.Mail namespace. So, it doesn't really have any learning curve for someone who already knows about the ASP.NET emailing libraries.

To simplify things, Mvc.Mailer namespace has an extension class for MailMessage that adds two handy methods to it - namely, Send() and SendAsync(). These methods simply relay to an instance of the SmtpClient class. So that your code doesn't need to deal with all these transport layer details and can stay at a fairly high level similar to the Controller Actions, you simply fire the view and forget about how it is actually sent to the output stream!

A Few Interesting Points

  • The idea to implement MvcMailer actually came while I was browsing ASP.NET MVC source code.
  • The idea originates from my Ruby on Rails background.
  • NuGet packaging seems to be a good way of releasing plugins for .NET applications!
  • The source code for MvcMailer has only tens of lines, if you want, you can take a look at this github page!

Interesting Updates

  1. Jan 28, 2011 - MvcMailer 0.7 is released. This version adds automated test support for code that use MvcMailer to send emails.
  2. Jan 28, 2011 - MvcMailer-Example project is pushed to github. Use the example project to get up and running with MvcMailer even more quickly!

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here