Understanding Routing in ASP.NET MVC (2024)

Before ASP.NET MVC, URLs in web application mapped to physical files at a disk location. So for example if you had a URL ‘hxxp://www.testurl.com/products/Default.aspx’ it simply meant there was a Default.aspx file in a ‘products’ folder at the root of the website. This URL had no other meaning. Any parameters it took was probably passed in the query string making it look like ‘hxxp://www.testurl.com/products/Default.aspx?productid=99’

Note: To avoid hyperlinks in this article, we have renamed http to hxxp. Wherever you see hxxp, please read it as http.

However if we built a MVC site for the same, the URL would probably look like ‘hxxp://www.testurl.com/product/’ and ‘hxxp://www.testurl.com/product/details/99’. By convention (and default) the first URL maps to the ProductController class with an action named Index. The second URL maps to the ProductController class with and action named Details. As we can see, MVC Routing helps abstract URLs away from physical files which by default maps to Controller/Action method pairs by default.

We will now go into details of how this mapping happens and how to modify the defaults. But before that, some best practices!

Routing and URL Etiquettes

The concept of clean URLs essentially came down from frameworks like Ruby. Some of the accepted conventions for clean URLs are:

1. Keep URLs clean: For example instead of ‘hxxp://www.testurl.com/products/Default.aspx?productid=99&view=details’ have ‘hxxp://www.testurl.com/product/details/99’

2. Keep URLs discoverable by end-users: Having URL parameters baked into routes makes URLs easier to understand and encourages users to play around and discover available functionality. For example in the above URL ‘hxxp://www.testurl.com/product/details/100’ would mean the product details for product id 100. But guessing numbers is no fun as we will see in the next practice.

3. Avoid Database IDs in URL: In the above examples we have used 100, which is a database id and has no meaning for the end user. But if it were to use ‘hxxp://www.testurl.com/product/details/whole-milk’ our users would probably try out ‘hxxp://www.testurl.com/product/details/butter’ on their own. This make points 1 and 2 even more relevant now.

However if IDs are unavoidable consider adding extra information in the URL like ‘hxxp://www.testurl.com/product/details/dairy-product-99/’

Clean URLs described above have the added advantage of being more ‘search robot’ friendly and thus is good for SEO.

With the - what (is routing) and why (we should have clean URLs) out of the way, let’s looking deeper into how routing works in MVC.

How does the Route Handler work

Quite sometime back I saw a Scott Hanselman presentation on MVC2 where he stopped the execution of sample MVC app on the Controller Action and then walked through the stack trace to show the inner workings of the MVC pipeline. I tried the same for the route handler and ended up with a 1000+ pixels stack trace, part of which is reproduced below. As highlighted below, the first thing that happens in the pipeline during transition from System.Web to System.Web.Mvc is the execution of all registered handlers.

Understanding Routing in ASP.NET MVC (1)

Fact is the RouteHandler is first to be executed. It follows these steps (not evident from the stack trace)

1. Check if route is static file on disk, if so the resource is served directly

2. If it’s not a static route, check if there is a custom route handler, if so it hands off the request to the custom route handler

3. If there are no custom route handlers it hands over to the default MVC Routing handler. Now that we have reached the route handler let us see how it treats routes

To see the entire pipeline refer to Steve Sanderson’s MVC Pipeline diagram here.

Understanding the default Route declaration

In ASP.NET MVC, by default a couple of routes are defined for you. With the introduction of WebAPI, another additional route is declared for WebAPI controller actions. Let us look at these routes and see what they imply.

Understanding Routing in ASP.NET MVC (2)

The Route labeled (1) is named ‘Default’ and it has a url template of type {controller}/{action}/{id}. Note the third parameter, which is an anonymous object with three properties, each of which matches a section in the url template.

The Route labeled (2) is information for MVC Routing to ignore anything that ends with an axd and having additional parameters. The {*pathinfo} is a wildcard for all query params.

Finally the Route Labeled (3) is for WebApi based controllers that derive of ApiController instead of the regular MvcController. Note WebApi routes are adding using the MapHttpRoute method. Also the route adds an ‘api/’ for every controller present. So even though you may have the ValuesController derive from ApiController and in the same folder as the HomeController, it will still be mapped to hxxp://<root>/api/Values. Here ‘api’ is the static part of a route.

Next we will see how we can add our own custom routes for MvcControllers.

Creating Custom Routes

Now if a user visited ‘hxxp://www.testurl.com/product/edit/1’ it would match the ‘Default’ route defined above and MVC would look for a controller called ProductController with an action Edit that takes an input parameter called id.

I have created a small application with a single Entity called Product that has the following properties

Understanding Routing in ASP.NET MVC (3)

This entity is serialized to the database using the EntityFramework and I built a Controller using the Visual Studio ‘Add Controller’ wizard. The files added are as highlighted below:

Understanding Routing in ASP.NET MVC (4)

Now if we look in the ProductController.cs, we will find Action methods for Get and Post Http actions for each of the above views. This makes the following default routes available

Understanding Routing in ASP.NET MVC (5)

Now let us see some Sample data

Understanding Routing in ASP.NET MVC (6)

As we can see above, we have two categories of products and 3 different names. Now each are identified by their IDs and you can use the Edit/Details/Delete action links to act upon them. However, if this list were to get much bigger, it would be really nice to have the ability to look at all items under the category ‘Electronics’ or ‘Electronics’ from ‘Sony’. Currently there is no such ‘filter’ available.

Let us implement this. First we add a parameter category to the Index action method, and filter the data we are getting from the Database and return it to the view.

Understanding Routing in ASP.NET MVC (7)

Now if we run the application and provide the URL

http://localhost:11618/Product/Index/Electronics

We will see the Index page but nothing has changed. It is still showing all Products.

Understanding Routing in ASP.NET MVC (8)

This is because the default route has specified a parameter called {id} but no {id} parameter was available in the Controller method. If we put a breakpoint in the Controller method, we will see that the ‘category’ parameter is coming in as null.

Understanding Routing in ASP.NET MVC (9)

How can we fix this?

..By defining a new Route that tells the routing handler how to navigate to an action method, when a ‘category’ parameter is specified for the Index method. The route is follows

Understanding Routing in ASP.NET MVC (10)

As we can see, we have defined a new route that expects a category parameter. Now when we provide Electronics as a parameter, we get a nicely filtered list

Understanding Routing in ASP.NET MVC (11)

Now we could add this URL to the Category column such that clicking on any category would filter the list.

Next, to continue making our URL more discoverable, we see we can add a Name filter too. Let us see what the Route and code looks like

Understanding Routing in ASP.NET MVC (12)

The change is simple, we have added {name} in the URL template and then specified it as a parameter in the anonymous object.

Next we updated the action method in the controller as follows

Understanding Routing in ASP.NET MVC (13)

We basically do a bit-wise operation to determine which of the parameters have been passed. 00 – No parameters, 01 – Name passed, 10 – Category Passed, 11 – Both name and category passed.

Of the four cases case 1: is interesting because as we see, we can mix clean urls with urls using named query strings. This is because the sequence of parameters is important. So we cannot mix up the sequence of parameters in URL and expect MVC to understand it. If there are optional parameters then parameters coming after the optional param must be named in the Url for the routing to work correctly.

So we have now seen what the default ASP.NET route means and how we can leverage routes in MVC to make discoverable URLs that respond to changes in the URL by presenting context aware data.

To round off, we see how we can use the Routing mechanism to generate URLs for us as I mentioned above.

Using MVC Routing to Generate URLs

Currently our Index page only shows links for Edit, Details and Delete. However we could convert the Category and Name column to have links that route MVC to pull up the index page with the selected category and name. In the Index.cshtml, we change the Razor markup as shown below to generate the link

Understanding Routing in ASP.NET MVC (14)

ActionLink and RouteLink

ActionLinks use the context of the current page while generating the target link. This results in the route-mapping happening based on the sequence in which the routes have been added. However if want to use a specific route to generate the URL we can use the RouteLink HTML helper. An example is shown below

Understanding Routing in ASP.NET MVC (15)

Here we are trying to setup the ‘Index’ heading into a link that navigates to the Product/Index page without any parameters. If we use Action Link, it will use the current page context and automatically add the available parameters, which will result in generated link always pointing to the current page. Instead if we use RouteLink and ask the routing framework to use the ‘Default’ route, then the link that is generated will point to Product/Index always. Thus the RouteLink html helper comes in really handy when we have to pick and choose which of the available routes we want to use to generate URLs.

Conclusion

With this, we come to a close of this post. We looked at the basics of MVC routing and understood what the default routing means. We also took a look at a few examples of how routing helps make URLs discoverable and how parameters can be passed using clean URLs.

To conclude, MVCs routing implementation frees up URLs from physical association to a file thus opening up a LOT of flexibility with how URLs can be presented and interpreted in an MVC application.

Remember Routing is not a ‘MVC only’ feature, we just covered how it works in an MVC application. More on ASP.NET and WebForms routing to come.

The entire source code of this article is on GitHub can be downloaded over here. Download as a zip file

See a Live Demo

This article has been editorially reviewed by Suprotim Agarwal.

C# and .NET have been around for a very long time, but their constant growth means there’s always more to learn.

We at DotNetCurry are very excited to announce The Absolutely Awesome Book on C# and .NET. This is a 500 pages concise technical eBook available in PDF, ePub (iPad), and Mobi (Kindle).

Organized around concepts, this Book aims to provide a concise, yet solid foundation in C# and .NET, covering C# 6.0, C# 7.0 and .NET Core, with chapters on the latest .NET Core 3.0, .NET Standard and C# 8.0 (final release) too. Use these concepts to deepen your existing knowledge of C# and .NET, to have a solid grasp of the latest in C# and .NET OR to crack your next .NET Interview.

Click here to Explore the Table of Contents or Download Sample Chapters!

What Others Are Reading!

Create and Print PDF in ASP.NET MVC

Implementing User Authentication in ASP.NET MVC 6

Dependency Injection in ASP.NET MVC 6 Views

Custom Model Binder in ASP.NET MVC

Action Method Selector in ASP.NET MVC

Access same Action Method by Multiple Roles in ASP.NET MVC using Configuration File

Was this article worth reading? Share it with fellow developers too. Thanks!


Author

Understanding Routing in ASP.NET MVC (17)

Sumit is a .NET consultant and has been working on Microsoft Technologies since his college days. He edits, he codes and he manages content when at work. C# is his first love, but he is often seen flirting with Java and Objective C. You can follow him on twitter at @sumitkm or email him at sumitkm [at] gmail

Understanding Routing in ASP.NET MVC (2024)
Top Articles
Latest Posts
Article information

Author: Kieth Sipes

Last Updated:

Views: 5359

Rating: 4.7 / 5 (67 voted)

Reviews: 82% of readers found this page helpful

Author information

Name: Kieth Sipes

Birthday: 2001-04-14

Address: Suite 492 62479 Champlin Loop, South Catrice, MS 57271

Phone: +9663362133320

Job: District Sales Analyst

Hobby: Digital arts, Dance, Ghost hunting, Worldbuilding, Kayaking, Table tennis, 3D printing

Introduction: My name is Kieth Sipes, I am a zany, rich, courageous, powerful, faithful, jolly, excited person who loves writing and wants to share my knowledge and understanding with you.