Understanding ASP.NET MVC Routing Mechanism

This article explains how the URL Routing mechanism works in ASP.NET MVC architecture.
What You’ll learn:

  • URL Routing
  • Working with Default and Custom Routes
  • Applying Constraints to Routes

Background

Before we start exploring how URL Routing works with MVC framework, Let’s have a quick overview MVC architecture.

By seeing this high level architecture diagram, we can say that the Controller will handle the user requests. The complete flow is as follows:

  • User requests for some data.
  • Controller will parse the request and gets the required data from Model (which will interact with the actual Datasource)
  • Controller inputs the data to the appropriate View for formatting and displaying it to the user.
  • View gets prepared by the data send by Controller and sends it back to controller.
  • Controller will finally sends it to User browser as a Response.

Introduction

By seeing the architecture diagram of MVC, we can easily tell that Model, View and Controller will play a major role in this framework. But

  • Where does the Routing stands in this framework?
  • Why is it so important?
  • How it will be helpful in MVC framework?

Let’s look at answers to all these questions.

If we closely observe the above figure, apart from Model, View and Controller, Routing has been included and it is first and only point of contact in MVC architecture to the user. Hence we can say that, Routing is the first important thing in MVC architecture.

Traditional way

Let’s first look at the traditional way of accessing the website content/data.

In webforms applications, every page is a .aspx page and that will be responsible for interacting with the user and display the user requested information on the page. When user requests for any of these pages or any resources by entering the URL and it maps to a physical file which is mapped to a directory on the web server.

Let’s understand this way by considering an example eCommerce site say www.myproducts.com.

For displaying list of products, we will create a page named products.aspx and it will given if the user requested for www.myproducts.com/products.aspx and for particular manufacturer products we used to pass manufacturer as query string parameter and filter the products within the page, this URL could look like this www.myproducts.com/products.aspx?manufacturerId=23. but we knew that human brains and even search engines are more comfortable with words instead of numbers. Here in this case we can not remember which manufacturer id is 23.

This is also an efficient of programming using webforms, but if we consider using MVC, it will add more comfort to the user with the use of URL routing.

MVC Routing

Unlike traditional webforms applications, MVC does’t provide physical files for the user requests. instead, each user request will be handled by the respective controller action methods. This complete flow will be taken care by Routing in MVC architecture.

As we have seen in figure – 2, the requests from user will be taken by Routing Engine and by comparing the requested URL with the Route Patterns which are registered in the application and calls the respective Controller/Action method.

The URLs which will server our eCommerce site products after implementing MVC Routing will be as follows:

www.myproducts.com/products/samsung/ for displaying all the products manufactured by samsung , which will be same as www.myproducts.com/products.aspx?manufacturerId = 10, where 10 represents samsung.

But for this to work we need to register the URL Route pattern in our application.

Route Patterns

In MVC Routing, its not one-to-one relationship between user requested url and the url pattern registered with application. instead, one URL pattern will serve for a group of similar URLs requested by user.

Route pattern will help the route engine to correctly parse the requested URL and map the request to respective Controller/Action method.

Configuring Routing

In ASP.NET MVC, Routing is supported by default. We can register route patterns in RegisterRoutes(RouteCollection routes) method from the Application_Start eventhandler of Global.asax file.

where in, RouteCollection is a collection of routes registered with the application.

 

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 
                              }
                );
}

From MVC 4.5, RegisterRoutes method has been moved to RouteConfig class under App_Start folder. But anyways this method must be called from Application_Start eventhandler of Global.asax.

As we can observe in RegisterRoutes method, there is a Default Route pattern registered and even we can add our custom route patterns into RouteCollection

Default Route Pattern

We can have a default routing pattern for our application to call a particular action method under a controller with some default parameters when a user doesn’t provide any arguments in the URL.

Here in our example, the default pattern is given as

{controller}/{action}/{id}

and the defaults for this pattern are given as

controller – Home

action – Index

Id – it’s an option parameter.

if we consider this pattern, controller and action are mandatory parameters whereas id is an optional one.

So, Let’s have a look at the valid URLs which can be handled by this Pattern.

Valid Patterns:

/Home/Index/5 – Valid ( it will call Index(int? id) action method of HomeController and it passes 5 as id)

/Home/Index    – Valid ( as Id is an optional parameter, this URL will still work and call Index() action method of HomeController)

/Home/            – Valid (in place of controller it will take HomeController but as we din’t mention any action       method, it will take it from defaults we set i.e., Index , Hence it would be equal to /Home/Index/)

/                      – Valid (it will take all the parameters from defaults, hence it would be equal to /Home/Index/)

Invalid Patterns:

/Home/Index/test – Invalid ( it will search for Index action method inside HomeController which takes string as   an argument, as we have only one Index method which takes int value as argument, this will raise an exception)

Please note that if the Index(int? id) method under HomeController has int argument instead of int? (nullable int), It will throw exception for /Home/Index , /Home , / – as it cannot parse null as integer.

Custom Routes

We have seen how can we use the default route which was created when we create MVC application. But we are not restricted to that, We can create our own custom routes according to our needs.

Let’s add one more route to the RouteCollection.

Say, we have a EmployeeController which has Action methods to get employee details by employee ID, to add a new employee or to delete an employee by an employee ID.

public static void RegisterRoutes(RouteCollection routes)
{
     routes.IgnoreRoute(“{resource}.axd/{*pathInfo}”);
     routes.MapRoute(
                   name: “Employee”,
                   url: “Employee/{id}”,
                   defaults: new { controller = “Employee”, action = “Details” }
                   );
     routes.MapRoute(
                   name: “Default”,
                   url: “{controller}/{action}/{id}”,
                   defaults: new { controller = “Home”, action = “Index”, 
                                   id = UrlParameter.Optional }
                   );
}

Look at the second route we just added to RouteCollection, Let’s what are all valid URLs to get Employee Details based on employee ID.

Valid Patterns:

/Employee/Details/10 – Valid ( it will be matched with the default URL pattern {controller}/{action}/{id} and searches for the Details action method under EmployeeController which takes id as an argument)

/Employee/10            – Valid (it will be matched with second custom route we defined. hence it will call the Details action method under EmployeeController and passes id as an argument)

Invalid Patterns:

/Employee/ – Invalid ( if considered only second route is there, as Id is not an optional argument, it will throw an exception. but it would match with first route and calls /Employee/Index if that action method exists.)

NOTE: The order or routes we add to RouteCollection is important. We always should add the more specific routes before the generic routes. otherwise, the generic routes like our default route will handle most of the url patterns and the specific routes will never be called.

Applying constraints on Route placeholder values

In the custom route we have added, the third placeholder {id} is expecting an interger as an Employee id. but we were not restricting the user to enter only integers. So he will get an exception if he/she uses a string value as the value for third placeholder {id}.

So to solve this, we can even apply constraints on the placeholder values along with the defaults we have set.

routes.MapRoute(
                name: “Employee”,
                url: “Employee/{id}”,
                defaults: new { controller = “Employee”, action = “Details” },
                constraints: new { id = @”\d+” }
                );

This is the modified version of our custom route. we have added a constraint of accepting only digits for the {id} placeholder. now it will not throw any exception if the user passes string value for {id} placeholder instead, it will consider it as invalid match and try searching for matching patterns.

That’s all about important parts of MVC Routing.

Hope you enjoyed! Happy Coding!!!

 

<p>I am a Consultant at Microsoft currently living in Hyderabad, India. My interests range from blogging to technology especially into /Web. I am also interested in movies and photography.</p>

Leave a Reply

Skip to toolbar