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

https://learnwithshahriar.wordpress.com/

In my last post I have discussed about the attribute routing and I believe that was quite enough to get started with the new featured offered both by MVC5 and WebAPI 2. In this post I will keep digging the same topic and together we will explore how we could impose certain constraints to get more control over routing.

Imposing Constraints

Imposing Constraints restrict how the parameters in the route template are matched. In the last post, I have shown how to search certain employee by their id. Now, lets say we also want the end user to search employee by Name. Also assume different view have be render in that case.

home/3 <–render “View A”
home/shahriar <–render “View B”

What we can do is to add another ActionResult which receives a string parameter. But only doing so does not solve our problem. We have to explicitly define and impose certain constraints to let the routing framwork work perfectly.

Notice the route carefully. In both cases routing framework hits the home controller and then based on the action parameter received it renders different view. If we just don’t explicitly tell the routing framework to impose certain constraints it just can’t fly you(the viewer) to the the appropriate action.

The general syntax for imposing certain constraint is {parameter:constraint}.

public class HomeController : Controller
{
      [Route("home/{id? : int}")]
      public ActionResult Employee(int id)
      {
           //Logic goes here
      }

      [Route("home/{name}")]
      public ActionResult Employee(string name)
      {
           //Logic goes here
      }
}

Here, the first route will only be selected if the “id” segment of the URI is an integer. Otherwise, the second route will be chosen. (“?”) symbol specifies that this parameter is Optional.

Ken Egozi posted a nice article regarding Attribute routing and there he posted Complete list of constraints with some example that I have added below:

Constraint Description Example
alpha Matches uppercase or lowercase Latin alphabet characters (a-z, A-Z) {x:alpha}
bool Matches a Boolean value. {x:bool}
datetime Matches a DateTime value. {x:datetime}
decimal Matches a decimal value. {x:decimal}
double Matches a 64-bit floating-point value. {x:double}
float Matches a 32-bit floating-point value. {x:float}
guid Matches a GUID value. {x:guid}
int Matches a 32-bit integer value. {x:int}
length Matches a string with the specified length or within a specified range of lengths. {x:length(6)}
{x:length(1,20)}
long Matches a 64-bit integer value. {x:long}
max Matches an integer with a maximum value. {x:max(10)}
maxlength Matches a string with a maximum length. {x:maxlength(10)}
min Matches an integer with a minimum value. {x:min(10)}
minlength Matches a string with a minimum length. {x:minlength(10)}
range Matches an integer within a range of values. {x:range(10,50)}
regex Matches a regular expression. {x:regex(^\d{3}-\d{3}-\d{4}$)}

Pay Close Attention : Some of the constraints, such as “min”, “maxlength”, “minlength” take arguments in parentheses.

To apply multiple constraints to a parameter, separated each constraint by a colon.

Rrestricting specific actions to specific HTTP verbs:
Existing attributes (e.g. [HttpGet], [HttpPost] and [AcceptVerbs]) are allowed ūüôā

And this brings to end of this topic. I have tried to cover up almost all the relevant major things regarding attribute routing but yet there has some mini tips and tricks that hasn’t been discussed here. I leave up those those tiny things for you. Hope you could figure out those tiny things by yourself. Happy coding ūüôā

Additional Resources:

  1. Maarten Balliauw’s blog
  2. Attribute routing in Web api 2

 

[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. Continue reading

Understanding the Routing framework

Asp.Net MVC Routing framework is the core of every Asp.Net MVC request. This means whenever an end user hits for a particular url, the routing framework came in to play.

Routing framework is basically a pattern matching system. The Routing System uses a series of rules listed in a routing table [App_Start\RouteConfig.cs] to determine which Controller and Action are executed in response to a request intercepted by the routing engine. When a URL is found to match a pattern, the routing engine attempts to match the text in the placeholders. If it cannot find a match, it returns a 404 HTTP Status Code. This whole concept is shown in the following image :

https://learnwithshahriar.wordpress.com/

Please note, Each routing rule contains placeholders that can match a controller, an action, and any number of variables. Variable data can be passed to the request handler without requiring a query string.

Now, Lets have a look on RouteConfig.cs file which is located under “App_Start” folder.¬† Routing engine basically matches the pattern of the received url against the RouteCollection registered in the following file.

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

            routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
            );
        }
    }

As you can see, the default code snipped that ships with the MVC template does not only used for providing a Name and URL  pattern but also defines a set of default parameter. In case,  the routing engine does not find a perfect match it starts filling values that are not provided by the URL from the default values.

If you want to map new routes you simply add your desired routes in this file(RouteConfig.cs). You add the route to the application by adding the Route object to the static Routes property of the RouteTable class. The Routes property is a RouteCollection object that stores all the routes for the application.

Note:

When adding new routes ALWAYS KEEP IN MIND that you have to add specific route on the top and followed by more generic route in the end. Otherwise your web app will never receive proper routing.

In the next post I will discuss about “Attribute Routing” . Till then have fun !