Adding features/functionality to ASP.Net MVC 3

3 minute read

Out of the box ASP MVC is a good framework, although in my opinion lacking quite a lot of functionality. That isn't a problem though as one of the greatest features of ASP MVC is how easily extensible it is. I've been working on my own framework, AutoMvc, to extend ASP MVC. This article will go over some of the additions I have made.

Restful Routing

I'm currently still working on this feature to allow for non-conventional routes, but at the moment it typically works by the following convention.

UsersController => /users

Within that controller you have to implement the following methods (ie actions), Index, Get, Post, Put, Delete. ie

 public ActionResult Get(int id)  
{
return View();
}
  • Index() => /users (GET)
  • Get(int id) => /users/123 (GET)
  • Post(User user) => /users (POST)
  • Put(User user) =>/users/123 (PUT or form-based POST as PUT)
  • Delete(int id) => /users/123 (DELETE or form-based POST as DELETE)

This helps create a clean, conventional way of handling resources and URL's. It also makes developers think about what they are creating which I find in turn makes for a cleaner design.

My RouteBuilder is based off the now outdated, Simply Restful Routing (that was part of MvcContrib), but I have since overhauled a lot of it.

Lower-case Routing

Just because I like things to be nice and clean, and it can cause less confusion for search bots crawling your site, I lower-case all routing in my framework. You can view the source code here.

Multiple Views Per Action

Rather than create more actions to return exactly the same data but a different view, or clog up your Action method with if statements deciding which view to return, you can implement a custom view engine to do the hard work for you.

I have extended the standard view engine by getting it to check the QueryString and RouteData for a "view" variable. If it exists, then the view is set to that value. For example:

/users?view=summary => loads the users/summary.cshtml view
Html.RenderAction("Get", "Users", new { id = 123, view = "info" }) => loads the users/info.cshtml view

This means your action method are kept clean and oblivious as to which view to return. Here is the source code for my ViewEngine.

Json/Xml Accept-Types

Given how often they are used, especially if using JQuery on your site, then you'll want to be able to return Json and XML from your action methods. Again this can be done without clogging up your Action methods by using an ActionFilterAttribute. The following can return HTML, XML or Json:

 public ActionResult Index()  
{
var users = Session.Get<User>();
return View(users);
}

As long as your objects are serializable then it will return whatever you specify via QueryString, Extension or Accept-Type. See my ResponseTypeFilter and Accept classes for the implementation.

Anonymouse Headers

One thing I can't stand is all the additional headers that ASP MVC adds to the response. I like to clear these out. Sure if a hacker wants to really know if I'm using ASP.Net they can find out, but it doesn't excuse having clean headers given how easy the implementation is. I created a CloakHttpHeaderModule to do the above for me.

SEO Friendly Urls

Given how important SEO is these days, not just in terms of search bots but what the user see's when looking through search result, I created a set of helper methods for easily checking the "slug" of a url.

For example, the url, /posts/123/improving-seo. If someone goes to the url /posts/123/a-nasty-slug-foo-bar then they are redirected via 301 to /posts/123/improving-seo

It does require implementation in your controller in the form of:

 public ActionResult Get(int id)  
{
var post = Session.Get<Post>(id);
if(!MatchesSlug(post.Name))
RedirectToSeoFriendly(post.Name);
return View(post);
}

The methods used above are implemented in my AutoMvcController class which extends the standard Controller class.

Updated: