[Attribute] Routing in ASP.Net MVC 5 / WebAPI 2 (Part I)

https://learnwithshahriar.wordpress.com/

In the last post I have discussed how the routing framework actually works, in this post I will discuss about one of the coolest latest feature offered by MVC5, WebAPI2 and its called “Attribute Routing”. Under the hood, attribute routing still maintains the same mechanism of routing framework.

So, right now you might be thinking if new routing feature(attribute routing) also use the same routing mechanism under the hood then where the twist actually came in the game? Well, over the last few years while developing large enterprise web apps it was found that as the project gets bigger and special cases accumulate it becomes hard to keep track of all those routes in a single file. Things get bit messy while developers have to write code to apply complex constraint. In most cases, they use a custom constraint by implementing IRouteConstraint and defining the custom logic in the Match method – if it returns true, the route is a match.

public interface IRouteConstraint
{
    bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection);
}

The problem with the Convention-based Routing is that since the routes are physically separated from the controllers they apply to, it often take some detective work to understand the relationships. With the hope to give a better development experience of this issues #Microsoft has adopted “attribute routing” feature in Asp.Net MVC5 and WebApi2 from Tim McCall.

As the name implies, Attribute routing uses attributes to define routes and it can be used on controller actions and even controller classes as well. In shortly, I will explain how these feature makes the life easier. But before that you have to enable this new feature in your solution. So, Lets do it first.

Enabling Attribute Routing
To enable Attribute Routing, we need to call the MapMvcAttributeRoutes method of the route collection class during configuration.

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        //Add the following line of code
        routes.MapMvcAttributeRoutes(); 

       //[Code Excerpt]
    }
}

As stated earlier, you can keep both the “Convention-based Routing” as well as the “[attribute] routing” under the same web app, if so then keep the following note in mind.

MapMvcAttributeRoutes() have to call before the Convention-based Routing.

Now, once we have enabled the attribute routing lets check out some examples.

::Example::

Defining a Route:
A route attribute has to be defined on top of an action method or on the top of a controller. In the following example I have declared the attribute routing on the top of action method named “About()”.

public class HomeController : Controller
{
       [Route("Users/about")]
       public ActionResult About()
       {
           ViewBag.Message = "You successfully reached USERS/About route";
           return View();
       }
}

Defining a Common Prefix:
If you want to specify a common prefix for an entire controller then instead of specifying [RoutePrefix] attribute on the top of each every action you should specify it in the controller level.

[RoutePrefix("Movie")]
public class HomeController : Controller
{
      //Route: Movie/Index
      public ActionResult Index()
      {
           ViewBag.Message = "You are in Home Index";
           return View();
      }

      //Route: Movie/About
       public ActionResult About()
       {
           ViewBag.Message = "You successfully reached USERS/About route";
           return View();
       }
}

Overriding a Common Prefix:
There could be situations where you might not want you actions to be response under the same route prefix. On such case you have to override the common route prefix. Doing so is easy.

Use a tilde (~) on the method attribute to override the route prefix.

[RoutePrefix("Movie")]
public class HomeController : Controller
{
      //Route: Movie/Index
      [Route]
      public ActionResult Index()
      {
           ViewBag.Message = "You are in Home Index";
           return View();
      }

      //Route: NewRoute/About
       [Route("~/NewRoute/About")]
       public ActionResult About()
       {
           ViewBag.Message = "You successfully reached NEWRoute/About route";
           return View();
       }
}

Defining a Default Route:
Now You know how to define a common prefix and how to override it in need. Our next target is to define a default route using attribute routing. First apply the [Route] attribute on the Controller level and then specify a default action as a parameter

In the following code snipped If not specified anything the routing framework will take the user to “/Movie/index” route.

[RoutePrefix("Movie")]
[Route("{action=index}")]
public class HomeController : Controller
{
      public ActionResult Index()
      {
           ViewBag.Message = "You are in Home Index";
           return View();
      }

      //Route: Movie/About
       public ActionResult About()
       {
           ViewBag.Message = "You successfully reached USERS/About route";
           return View();
       }
}

Note: To overriding the default route just specify the specific route on specific action !

Optional URI Parameter:
To make any parameter optional add a question mark to the Route parameter.

public class HomeController : Controller
{
      [Route("home/{id?}")]
      public ActionResult Employee(int id)
      {
           ViewBag.Message = "You are in Home Index";
           return View();
      }
}

Default Value in URI Parameter:
To specify any parameter as default initialize a value in the route parameter.

public class HomeController : Controller
{
      [Route("home/{type=en}")]
      public ActionResult Search(string type)
      {
           ViewBag.Message = "You are in Home Index";
           return View();
      }
}

The post is getting bigger. So, I will discuss rest of the part (Area, Route Constraints, Custom Route Constraints, Route Name ) of attribute routing in the next post. Stay tuned.

Additional Resource: http://benfoster.io/blog/improving-aspnet-mvc-routing-configuration

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s