Category Archives: ASP.NET MVC

How To Receive E-mails in ASP.NET MVC using MailGun

Mailgun has a fantastic API for doing a lot of stuff with e-mail. Not only is it a breeze to use their dedicated SMTP service to send a lot of e-mails with great deliver-ability – it is also very powerful for routing e-mails back to your application.

There’s a lot of use cases for routing e-mails back to your app, a few includes:

  • Reply to messages within your app
  • Send files to your app from any device, without providing native apps for any particular devices
  • Execute commands from e-mail to e.g. run a background task, or whatever makes your users happy

Heck, you can even transfer money using e-mail. Just write $10 in the subject line, send it to your friend and add cash@square.com to the CC recipients list and you’ve just sent money via e-mail.

Mailgun routes

To route back e-mail to your application, you need two things:

  1. Setup an MX record of a domain so that it points to mxa.mailgun.org
  2. Add a route within Mailgun that forwards to your web app

Setting up the MX record is beyond the scope of this blog post. You can take a look at the Mailgun docs and find guides for common hosting providers.

To setup a route, you need to login to Mailgun, find the Routes tab and create a new route with a match criteria that let’s you filter by recipient, header etc. Read more about routes in the docs.

Receiving messages via HTTP

Whenever an e-mail matches the criteria of the route, Mailgun will issue an HTTP POST request to the URL you specified as part of the forward() action.

To receive the request in a controller/action in ASP.NET MVC, you can use the following code:

Mailgun listens to the HTTP status code you return:

For Route POSTs, Mailgun listens for the following codes from your server and reacts accordingly:

If Mailgun receives a 200 (Success) code it will determine the webhook POST is successful and not retry.
If Mailgun receives a 406 (Not Acceptable) code, Mailgun will determine the POST is rejected and not retry.
For any other code, Mailgun will retry POSTing according to the schedule below for Webhooks other than the

And will retry for 8 hours:

If your application is unable to process the webhook request but you do not return a 406 error code, Mailgun will retry (other than for delivery notification) during 8 hours at the following intervals before stop trying: 10 minutes, 10 minutes, 15 minutes, 30 minutes, 1 hour, 2 hour and 4 hours.

3 Reasons Why Dedicated ViewModels in ASP.NET MVC is a *MUST*

I’d argue that using dedicated view-models in ASP.NET MVC (or any other MVC framework) is one of the things that has changed the way I work for the better. And for the better I mean more maintainable code, better designed code, more robust code — just better in all ways measurable.

Here are three reasons why you should use truly dedicated view-models for any view in ASP.NET MVC.

1. Abstract code beyond your control

If you work on a web team, that is part of a larger team you cannot expect to always have the entire back-end ready at the time you want to start coding a feature for the front-end. But why wait? Even if you don’t have the service layer, the domain models or the database ready, you can just easily create dummy instances of your view-model in a controller and return that to the view.

You can get started coding the UI, the JavaScript, maybe hook up your Backbone models or anything similar.

You are also in complete control of the design of the view-models, and it often turns out that they end up a hell of a lot different from the domain models.

2. Keep view oriented data annotations out of the domain model

You want to use both validation attributes, UIHints, template information and a lot of other view oriented stuff that should stay inside the MVC project.

The problem is that if you throw all these things on the domain model, you suddenly have a dependency on ASP.NET MVC and Razor which means that you must add reference to these dependencies from your lower tiers. Not good!

3. Defend your JavaScript from outside changes

JavaScript is playing a bigger and bigger part in modern web development. So the more JavaScript your write that manipulates your view-models, the more exposed you become to outside changes.

Having a dedicated view-model makes you in control, and not the DBA or any other dude who doesn’t care about the front-end.

How to avoid repeating yourself

It’s probably the worst argument against view-models, that you end up repeating the domain-models. If you think that, you’ve missed something.

The point of a view-model is to make it as closely tied to the view as possible. This will make the view a lot more simple, which is a good thing.

For mapping a domain-model to a view-model and vice-versa, I use AutoMapper which is extremely simple, yet powerful.

Backbone.js Compatible Routes for, non-Web API, ASP.NET MVC projects

Backbone.js has become my JavaScript MV* framework of choice (you do use a JavaScript MV* framework, to structure JavaScript, right?). I find myself using ASP.NET MVC for less and less that has something to do with views, and other stuff that belongs on the client.

The server, being ASP.NET MVC, is the new backend now a days. I’m sure that’s how Microsoft sees it as well, with the release of Web API.

cc by-nc-nd Bruno Monginoux www.photo-paysage.com & www.landscape-photo.net

When using models in Backbone, and specifying the urlRoot setting, Backbone will automatically construct URLs to do CRUD operations against your server. It uses RESTful URLs, and regular ASP.NET MVC controllers are not compatible with those out of the box.

Consider this Backbone model and collection:

var Account = Backbone.Model.extend({
	urlRoot: "/accounts"
});

var AccountCollection = Backbone.Collection.extend({
	model: Account,

	url: "/accounts"
});

When you save a new Account, Backbone will make a POST request to your server expecting to hit your AccountsController. But with regular MVC controllers (non-Web API, that is) the routing won’t succeed, since the default {controller}/Index action only works with the default, parameter less GET request.

You might think that this controller will work:

public class AccountsController : Controller
{
	[HttpGet]
	public JsonResult Index()
	{
		List accounts = new List();
		accounts.Add(new Account { Id = 1, Name = "Account 1" });
		accounts.Add(new Account { Id = 2, Name = "Account 2" });
		accounts.Add(new Account { Id = 3, Name = "Account 3" });

		return Json(accounts, JsonRequestBehavior.AllowGet);
	}

	[HttpGet]
	public JsonResult Index(int id)
	{
		return Json(new Account { Id = id, Name = "Account " + id }, JsonRequestBehavior.AllowGet);
	}

	[HttpPost]
	public JsonResult Index(Account model)
	{
		return Json(model);
	}

	[HttpPut]
	public JsonResult Index(int id, Account model)
	{
		return Json(model);
	}

	[HttpDelete]
	public ActionResult Index(int id)
	{
		return View();
	}
}

But as mentioned before, the default Index routes doesn’t work that way. This won’t even build, since the method signature of Get and Delete are the same.

Route constraints to the rescure

Ideally we want our controller to look like the following:

public class AccountsController : Controller
{
	[HttpGet]
	public JsonResult GetAll()
	{
		List accounts = new List();
		accounts.Add(new Account { Id = 1, Name = "Account 1" });
		accounts.Add(new Account { Id = 2, Name = "Account 2" });
		accounts.Add(new Account { Id = 3, Name = "Account 3" });

		return Json(accounts, JsonRequestBehavior.AllowGet);
	}

	[HttpGet]
	public JsonResult Get(int id)
	{
		return Json(new Account { Id = id, Name = "Account " + id }, JsonRequestBehavior.AllowGet);
	}

	[HttpPost]
	public JsonResult Create(Account model)
	{
		return Json(model);
	}

	[HttpPut]
	public JsonResult Update(int id, Account model)
	{
		return Json(model);
	}

	[HttpDelete]
	public ActionResult Delete(int id)
	{
		return View();
	}
}

So for this to work, we need to point the individual HTTP verbs to their own action. This can be done by adding an HTTP method route constraints, when mapping routes in your RouteConfig (or Global.asax):

routes.MapRoute("Model_GetAll", "{controller}", new { action = "GetAll" }, new { httpMethod = new HttpMethodConstraint("GET") });
routes.MapRoute("Model_GetOne", "{controller}/{id}", new { action = "Get" }, new { httpMethod = new HttpMethodConstraint("GET"), id = @"^\d+$" });
routes.MapRoute("Model_Post", "{controller}", new { action = "Create" }, new { httpMethod = new HttpMethodConstraint("POST") });
routes.MapRoute("Model_Put", "{controller}/{id}", new { action = "Update" }, new { httpMethod = new HttpMethodConstraint("PUT") });
routes.MapRoute("Model_Delete", "{controller}/{id}", new { action = "Delete" }, new { httpMethod = new HttpMethodConstraint("DELETE") });

Now you can code away in Backbone, and always hit the correct MVC controller actions. If you want to avoid this, upgrade your MVC app to MVC 4 and use Web API controllers. They support this out of the box.

Unit Testing ASP.NET MVC Controller Action contains specific ActionFilter Attributes

ActionFilters in ASP.NET MVC are great.

You can now easily share logic between controllers without having to inherit from a base controller, that does the common work.

I have a content heavy application that supports a set of layouts. Each layout is rendered by setting the Layout view dynamically, which I do from an ActionFilter. My ActionFilter is fully tested, but when you delegate work to an ActionFilter, you should write a test that ensures the filter is defined on the action.

Not surprisingly, this is very simple and relies on reflection (Download from Gist: https://gist.github.com/2605628):

/// <summary>
/// Verifies the controller action, contains an attribute of the specified attributeType.
/// </summary>
/// <param name="controller">The controller.</param>
/// <param name="action">The action method.</param>
/// <param name="attributeType">Type of the attribute to look for.</param>
/// <returns>Returns true if the attribute was present on the action. Otherwise false.</returns>
public static bool VerifyControllerActionAttribute(this Controller controller, Func<ActionResult> action, Type attributeType)
{
    MethodInfo methodInfo = action.Method;
    object[] attributes = methodInfo.GetCustomAttributes(attributeType, true);
    return attributes.Any(a => a.GetType() == attributeType);
}

And the usage looks like this:

[TestMethod]
public void Index_ContainsTemplateLayoutAttribute()
{
    HomeController controller = new HomeController();
    bool containsAttribute = controller.VerifyControllerActionAttribute(controller.Index, typeof(TemplateLayoutAttribute));
    Assert.IsTrue(containsAttribute);
}

Need an introduction? Watch a video about unit testing ASP.NET and MVC based web apps on Vimeo, published by Typemock.

ASP.NET MVC Localize Numeric (data-val-number) Validation

Another buggy experience in ASP.NET MVC. This has to do with validation, more specifically numeric validation. Whenever you have a numeric property on your view models, ASP.NET MVC automatically adds some implicit validation to ensure that whatever entered in fact is a numeric value.

Might be good in most cases, but here’s the problem. The validation mechanism writes the error messages in english. So for any app that targets a non-english audience, this needs to be changes.

But that’s easier said than done. The code in ASP.NET MVC that generates the error message for the implicit numeric validator, looks like this:

private static string MakeErrorString(string displayName) {
  // use CurrentCulture since this message is intended for the site visitor
  return String.Format(CultureInfo.CurrentCulture, MvcResources.ClientDataTypeModelValidatorProvider_FieldMustBeNumeric, displayName);
}

To make matter worse, this is a method from an internal, sealed class. They didn’t want you to change this.

The only option is to remove the validator, and get rid of the implicit validation. To be honest, I prefer to take care of validation myself, through data annotations on my view models. I don’t like when too much gets done implicitly. I want to be in control, and I want to know what is going on.

You can remove the validator in Global.asax:

foreach (ModelValidatorProvider prov in ModelValidatorProviders.Providers) {
  if (prov.GetType().Equals(typeof(ClientDataTypeModelValidatorProvider))) {
    ModelValidatorProviders.Providers.Remove(prov);
    break;
  }
}

If you’d like to keep the numeric validation, but be able to override the error message, there’s a great way to roll your own ClientDataTypeModelValidatorProvider that does this the right way.

Things will get better

I was browsing through the source code of ASP.NET MVC 4, and found a changeset that looks like will fix this issue. In short, it will be possible to define your own ResourceClassKey, and the MVC framework will use that before using default error messages. Nice!

 

ASP.NET MVC 3 Windows Authentication problem – redirects to Account/Login

ASP.NET MVC 3 has its quirkiness here and there. Sometimes it’s a lack of support for something, and other times it’s downright buggy.

An issue I came across recently, is something to do with Windows Authentication. There’s a lot of resource on the web on how to run ASP.NET MVC with Windows Authentication. There’s even a project template, the Intranet site, which ships with MVC 3. It should be a no-brainer!

The issue I came across, prevented ASP.NET from using Windows Authentication. Even though I had set authentication mode to Windows in Web.config:

<authentication mode="Windows" />
<authorization>
  <deny users="?" />
</authorization>

And disabled anonymous authentication on the website in IIS - it always redirected all requests to /Account/Login, as if it was using some sort of default Forms Authentication.

This coursed a server error – the dreaded Yellow Screen of Death, since I didn’t have a login form on my site, I had no controller/action for Account/Login.

Known issue

After searching the web for a while, I came across the release notes on the ASP.NET MVC website. At the bottom, there’s a section called ‘Known issues‘, and one of the last issues reads:

There’s a known issue that causes Forms Authentication to always redirect unauthenticated users to ~/Account/Login, ignoring the forms authentication setting used in Web.config. The workaround is to add the following app setting.

      <add key="autoFormsAuthentication" value="false" />

And much to my disappointment, this didn’t do the trick! Long story short, it turned out that I needed another setting as well, as pointed out in the comment of this Stackoverflow question:

<add key="enableSimpleMembership" value="false"/>

After adding the magic settings to my Web.config, everything worked as it should – and Windows Authentication on ASP.NET MVC is now a no-brainer!

How to Send HTML E-mail from an ASP.NET MVC Controller

As I argued about a year ago, any modern piece of software needs to send e-mail. It needs to connect, and reach its users. Back then I showed how to send templated HTML e-mail, using the little known MailDefinition class in C#.

Today, there’s an even better approach. The main problem with the old solution, was that the templates were plain, old, flat and boring HTML templates. Any sort of dynamic content, were limited to what a simple replace could do.

The better approach that I’m using now, is the awesome ActionMailer.NET package. It’s right there within Visual Studio, if you have Nuget – which I’m sure you do.

Why is it better?

ActionMailer.NET is better, first of all because the templates for your e-mails are just regular ASP.NET MVC views. That means you can strongly type those view and supply it with a model. All the stuff you can do in an ASP.NET MVC View (Razor or WebForms – your choice) – you can now send via E-mail.

It’s very easy to use

You simply start by creating a new Controller in your ASP.NET MVC web application that will take care of sending all the e-mails. Along with the controller, you add a folder for the views.

public class MailController : MailerBase
{
    public EmailResult VerificationEmail(User model)
    {
        To.Add(model.EmailAddress);
        From = "Martin Normark <mysite@email.com>";
        Subject = "Welcome to My Blog!";


return Email("VerificationEmail", model); } }

Notice how you can set the from name, as well as the e-mail address. Neat stuff. If you want to do something just before or after an e-mail is sent, you can play around with the OnMailSending and OnMailSent by overriding the default implementation.

protected override void OnMailSending(MailSendingContext context)
{
    base.OnMailSending(context);
}

protected override void OnMailSent(System.Net.Mail.MailMessage mail)
{
    base.OnMailSent(mail);
}

Maybe you want to save the e-mail in your database for future reference, logging etc.

One thing I’ll do one day, is combine this with the premailer Ruby project, that optimizes your HTML e-mails for rendering in e-mail clients, by moving your CSS inline.

ASP.NET MVC View Page Editor in Visual Studio 2010 Beta 2 won’t recognize HTML tags

I love the new IntelliSense dialog in Visual Studio 2010 Beta 2, that ScottGu has blogged about. But when editing an ASP.NET MVC View Page in Visual Studio 2010 Beta 2, you end up fighting the IntelliSense. That is because IntelliSense and the HTML Editor doesn’t recognize *any* HTML tags.

image

Trying to add a simple paragraph tag in HTML suggests a panel (code snippet). When you finish the P tag, by typing >, the result is this:

image

Pretty annoying to fight with IntelliSense when you want to code! I thought you might be able to fix this, by deleting all the new ASP.NET specific code snippets in the “C:\Program Files\Microsoft Visual Studio 10.0\Web\Snippets\HTML\1033\ASP.NET” folder.

This actually works. Now you can actually see the ASP.NET MVC code snippets, that was hidden in the masses of the ASP.NET ones.

image

But it still has all the ASP.NET Server Controls listed. I thought I could get rid of these by removing a namespace reference to System.Web in the Pages section of Web.config. But that is not present. So I don’t know how to fix that.