Integrating Postmark into ASP.NET MVC
Tags: .NET, MVC April 8th, 2010I was excited when I first heard about Postmark as it answered a problem that I’ve faced on many projects in the past – how do you send “triggered” emails from your web application? By triggered emails, I mean one time, one hit emails sent to a specific user in response to a specific action e.g. user registration, order confirmation etc.
The answer in the .NET world has always been to “roll your own” email service using the System.Net.Mail namespace and the SMTP capabilities of IIS. Whilst the process of writing this code is straightforward, the hard part is not developing the code, but all the stuff that the developers don’t actually think about. As Postmark describe:
If you’ve ever built or launched a web application, you know that setting up an SMTP server is pretty easy. The basic steps can have you up in running in minutes. What you may not know, is that doing it correctly is complex. For instance:
- Setting up authentication like SPF and DomainKeys
- The importance of Reverse DNS
- Managing connection and message rules for each ISP
- Applying for ISP whitelisting and feedback loops
- Accreditation with ISIPP and ReturnPath
- Tracking bounces and spam complaints
- Understanding volume over time
These problems have hit me in the past, which is why I’d always look to a third party service for sending emails from my application. There are many services that provide campaign style email sending (i.e. generic or targeted marketing emails sent to a list of users), however finding a company that provides a triggered service (via an API) has always proved impossible. On a recent project, we found a company that provided this service, only to find out that they were deprecating it 3 weeks prior to our application going live. Nice.
So, like I said, I was very excited to hear about Postmark and signed up for the private Beta trial straight away. The service has recently gone live, so now seemed like a good time to knock up a little demo application…
The Demo App
I mainly develop in .NET, especially when working for clients at EMC Consulting, so wanted to focus on this for the demo as it is likely that this will be the way I will use Postmark in anger on a “real” project. There’s already a .NET API available on Github so I set about hooking this up to an MVC application.
My application is just one screen with a text box for an email address. Clicking the submit button will send a test email to the email address entered via the Postmark service.
Home Controller
As I only have one screen, I only need one controller. My HomeController handles both the GET and POST requests to the root URL – the first simply returns the view and the second calls my messageSender to send the email and redirects back to the view.
A couple of things to note – my controller is talking to an IMessageSender, injected into the constructor, to keep the controller simple. There is no mention yet of anything to do with Postmark, or any implementation of how this message is going to be sent – to put it simply, the controller shouldn’t know or care about this implementation detail – it just handles the flow of the application.
The second thing is that the controller redirects back to the Index action after the form is submitted – i.e. it issues a HTTP 302 response to redirect back to the root URL. This follows a pretty standard pattern in web applications called Post – Redirect – Get which ensures that after a user submits a form, if they hit refresh in the browser, they’re not going to re-submit the form again. So, if the email is sent successfully, or even it something went wrong, refreshing the browser doesn’t initiate another POST request.
public class HomeController : Controller
{
private readonly IMessageSender _messageSender;
public HomeController(IMessageSender messageSender)
{
_messageSender = messageSender;
}
public ActionResult Index()
{
return View();
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Index(string email)
{
var response = _messageSender.SendMessage(email);
TempData["Message"] = response;
return RedirectToAction("Index");
}
}
Postmark Message Sender
Whilst the HomeController is working against an IMessageSender, we’re going to need a real implementation in order to actually send messages. This is where our Postmark integration comes in. I’m using the Postmark .Net API in order to call the Postmark service, which requires two configuration values to be set – the API Key and the sender email address. These need to be valid values according to my Postmark account. For simplicity’s sake, I’m storing this in App Settings in my web.config:
<appSettings> <clear/> <!-- Set this to your email server's API token (Guid) --> <add key="ServerToken" value="XXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXX"/> <!-- Set this to a valid sender signature (email address) --> <add key="From" value="user@email.com" /> </appSettings>
I don’t like hitting configuration sources directly as it makes classes hard to test, so I like to encapsulate configuration as some kind of service and inject that in to anything that needs it. Our PostmarkMessageSender therefore depends on an IConfigurationSource in order to access these values.
The IMessageSender has one method signature, SendMessage() which takes an email address input parameter and returns a string response – either a success message, or an error message according to what happened when trying to send the email.
Here’s my implementation:
public class PostmarkMessageSender : IMessageSender
{
private readonly IConfigurationSource _configuration;
public PostmarkMessageSender(IConfigurationSource configuration)
{
_configuration = configuration;
}
public string SendMessage(string email)
{
var client = new PostmarkClient(_configuration.ServerToken);
try
{
var response = client.SendMessage(BuildMessage(email));
if (response.Status != PostmarkStatus.Success)
{
return response.Message;
}
}
catch (ValidationException ex)
{
return ex.Message;
}
return "Message sent successfully!";
}
private PostmarkMessage BuildMessage(string email)
{
return new PostmarkMessage
{
From =_configuration.FromAddress,
To = email,
Subject = "Postmark ASP.NET MVC Demo",
HtmlBody = "Hello!",
TextBody = "Hello!",
};
}
}
Framework
My IConfigurationSource implementation calls directly into the web.config application settings;
public class WebConfigurationSource : IConfigurationSource
{
public string ServerToken
{
get { return WebConfigurationManager.AppSettings["ServerToken"]; }
}
public string FromAddress
{
get { return WebConfigurationManager.AppSettings["From"]; }
}
}
And the dependencies are wired up using a Ninject module:
public class WebModule : NinjectModule
{
public override void Load()
{
Bind<IMessageSender>().To<PostmarkMessageSender>();
Bind<IConfigurationSource>().To<WebConfigurationSource>();
}
}
Which is configured for the MVC application in the global.asax.cs by inheriting NinjectHttpApplication and overriding the CreateKernel() method:
public class MvcApplication : NinjectHttpApplication
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
}
protected override void OnApplicationStarted()
{
RegisterRoutes(RouteTable.Routes);
RegisterAllControllersIn(Assembly.GetExecutingAssembly());
}
protected override IKernel CreateKernel()
{
return new StandardKernel(new WebModule());
}
}
And that’s it – this whole app took me about 30 minutes to build (and another 30 mins to make it look pretty
) and I now have a fully functioning email-sending application. This is a fairly simple and trivial example, but it shows just how easy this is to do. A real-world application might have requirements around batching up emails and sending them asynchronously or sending to multiple address. However, hopefully this shows that whatever the requirements, you now only have to focus on the code and let somebody else think about the actual task of sending the messages – and producing the stats:
Source code
Source code for this demo application is available on Github at the following location. Enjoy…

April 10th, 2010 at 1:55 pm
Great post, I have never heard about Postmark. Usually I used some gmail account. But it has a limited set of features. Postmark is really great. And thanks a lot for sharing code!
December 25th, 2011 at 12:43 pm
I guess it up there pippa middleton topless half of you carry.