BASICS OF ROUTING IN MVC


In simple words: Routing is process of mapping incoming request url to a resource, which can serve the request. 
Why do we need  routes? Aren’t our web application and web servers not capable of matching user request to specific resource/web page (.html or aspx or php) on the server? The answer is “Yes”. However, let say user requests a page or URL that doesn’t exist on server at all. What do we do in that case? Showing 404 page always is not good idea. This is where routing comes to rescue. Using routing you can define routes that need not always map against physical file on the server


Let us make it more clear with an example. User request a page http://AbcShopping.com/Products/SmartPhone.aspx? Id=2.

In traditional applications, we would need to have webpage “SmartPhone” under “Product” folder, so that web application renders the appropriate web page to the user. But if we define a custom routes within our application then routing framework gives flexibility type URL like this:
http://AbcShopping.com/Products/ SmartPhone /Iphone7  


Advantages of Routing

  • It makes more user friendly URL and easy to remember for the user and optimized for search engines too.
  • Can create URL with any sort of pattern based on the requirement. 
  • It also adds value when it comes to building Url for REST based web API. 

Internals of Routing

So how does routing engine maps a route against URL entered by user? The routing table maintains list of routing pattern, which can be of type:{controller}/{action}/{id}.

When user sends a request, routing engine will compare request URL with every routing pattern that is defined in the RouteTable. When match is found, corresponding controller and action method is executed, if no match is found then 404 page is displayed.


Routing flow-chart



MVC Routing




Routing Configuration

The custom routes can be configured by adding routing to RouteConfig.cs, which located under App_start folder.

public class RouteConfig
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Products", action = "SmartPhone", Type = UrlParameter.Optional }
            );
        }
    }

The MapRoute method takes 3 named parameters
  •  Name – Name of the route
  •  Url – Defines pattern for the route. Here the pattern is {controller}/{action}/{type} – where controller, action, type are place holders.When request: http://AbcShopping.com/Products/SmartPhone/Iphone  arrives, first it will search for all list of controllers that can map against word “Products”. When controller is found, action method namely “SmartPhone” is invoked with “Iphone” as input parameter.
  •  Default –  Defines default controller and action methods if not provided as part of request. If user request only the website name I.e. http://AbcShopping.com then by default it will be redirected to http://AbcShopping.com/Products/SmartPhone


Custom Routes

You can add more than one custom route to your configuration as shown below.

public class RouteConfig
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
   routes.MapRoute(
                "Custom",
                "DigitalProducts/{Keyword}”
                new { controller = " DigitalProducts ", action = "Search”});

            routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{Type}",
                defaults: new { controller = "Products", action = "SmartPhone", Type = UrlParameter.Optional }
            );
        }
    }

 So let us test routing configuration with different URL requests. And we have test results below. The third request doesn't match any route because it doesn't match any routing pattern defined in the configuration.


URL Pattern Matches?
DigitalProducts/Search/Tablet  Custom Yes
DigitalProducts/Tablet Custom Yes
Products/1 NA No
Products/SmartPhone/1 Default Yes
  

Routing Constraints

We can define routing constraints within each route, so that only valid inputs are passed to action methods. In the below routing configuration, we have restricted ProductId value to integer datatype.

routes.MapRoute(
    "Product",
    "Product/{productId}",
    new {controller="Product", action="Details"},
    new {productId = @"\d+" }
 );




  • If incoming request is http://localhost/Product/1 then it will be accepted and product controller with action method: details will be invoked with id=1 as parameter.
  • If incoming request is http://localhost/product/iphone then it will not be accepted.


So this is about basics of routing. I hope you enjoyed this article. Please feel free to share your comments.  I will get back to you soon with answers.

Happing coding,
MK




No comments: