Introduction to ASP.NET Core MVC Routing
This is part 32 of ASP.NET Core. In this video, we'll discuss routing in ASP.NET Core MVC. There are two routing techniques: conventional routing and attribute routing. In this video, we'll discuss conventional routing, and in our next video, attribute routing.
When a request from the browser arrives at our application, it is the controller in the MVC design pattern that handles the incoming HTTP requests and responds to the user action. The incoming request URL is mapped to a controller action method. This mapping is done by the routing rules defined in our application.
Let's look at an example. Consider this incoming request URL: http://localhost:1234/home/index. That is the server that's hosting our web application. In our case, it's the localhost. And then we have two path segments: /home/index.
So the first path segment, /home, is mapped to the HomeController class in our application. And the second path segment, index, it is mapped to the Index action method within our HomeController.
Mapping URL Segments to Action Method Parameters
Now let's look at another example. Notice in this URL we have three path segments: /home/details/1. As usual, the first path segment, /home, is mapped to the HomeController. And the second path segment, /details, is mapped to the Details action method within our HomeController. And the third path segment, the value 1, that is mapped to the id parameter on the Details action method. So this mapping is done by the routing rules defined in our application.
Let's look at this in action. Notice within our HomeController class, we have two public methods: Index and Details. At the moment, this Details action method is retrieving employee details whose ID is 1. At the moment, we have hard-coded the employee ID to one. So instead of hard-coding it, let's pass the value as a parameter. I'm going to name the parameter id, and we're going to use this id parameter here instead of hardcoding it. With all these changes in place, let's run our application.
Running the App and Examining URL Behavior
Notice we see the list of employees. Now we know it is this Index action method within our HomeController that is returning us the list of employees. Now if we take a look at the URL, within the URL we don't have those path segments /home/index. So the obvious question that comes to mind is, how is this Index action method within our HomeController executed when we navigate to the root application URL?
We'll answer that question in just a bit. For now, let's navigate to /home/details/1. Notice we see the details of the employee whose ID is one. Now let's change the ID to two, and we see that employee's details. So this route, /home/details/2, is mapped to the Details action method within our HomeController, and the value 2 is mapped to this id parameter.
The Role of UseMvcWithDefaultRoute
This mapping is done by the routing rules configured within our application. But if you recollect from our previous videos in the series, we have not explicitly configured any routing rules within our application. So the obvious question that comes to our mind is, how are these routes mapped to these controller action methods?
Well, if we take a look at this Startup.cs file, we have this Configure method. If you recollect from our previous videos in the series, it is this method that we use to set up the request processing pipeline for our application. Within this method, we are calling this extension method, UseMvcWithDefaultRoute. As you can see from the IntelliSense, this method adds MVC support to our application's request processing pipeline with a default route. We'll look at the default route in just a bit. For now, let's comment the call to this method. Without this method, our application does not have MVC support.
But there is another way to add MVC support, and that is by using the UseMvc method. The difference between these two methods is, as the name implies, this UseMvcWithDefaultRoute method adds MVC support with a default route configured, whereas this method only adds MVC support. It does not configure any default routes for our application. So now with this setup in place, let's run our application and see what happens.
Configuring Routes Manually with UseMvc
Notice when we refresh the page, we see a 404 error. This is because at the moment, within our application, we don't have any routes configured. As a result, our application does not know how to handle this incoming URL. So let's configure routes for our application. We do that by using this UseMvc method. Notice from the IntelliSense, this method has got two overloaded versions. We are going to use this overloaded version that takes an Action<IRouteBuilder> as a parameter. I'm going to name it routes.
Notice from the IntelliSense, the type of this routes parameter is IRouteBuilder. And this IRouteBuilder interface has got a MapRoute method, which we use to configure the routes for our application.
Defining a Custom Route Template
Again, as you can see from the IntelliSense, every route has got a name and a template. I'm going to name our first route default. The second parameter is the template. The template specifies the URL pattern of the route.
Now if we take a look at this URL, we want to map this first path segment in the URL to a controller in our application. So within double quotes, I include a pair of curly braces and then specify controller. The second path segment in the URL is the name of the action method, and notice the action method and the controller are separated with a forward slash. So I'm going to include a forward slash here, and then another pair of curly braces, and then the word action. The next segment in the URL is this value 2. Again, notice between this 2 and the action method name, we have a forward slash, so I'm going to include another forward slash here, followed by another pair of curly braces, and then name the parameter id.
With this route template in place, let's save our changes and take a look at the browser. Notice now when we reload the page, we see employee details whose ID is 2. So with this route template in place, the first URL path segment here, home, is mapped to the HomeController. We don't have to have the word "controller" in the URL because MVC will automatically add the word "controller" to home and look for HomeController within our application. And then the second path segment, details, that's mapped to the Details action method. And the third path segment, that is this value 2, is mapped to the id parameter. At the moment, on our Details action method, we have a parameter that has the same name, id. So this value 2 will be mapped to this id parameter. This mapping is done by a process called model binding. We'll discuss model binding in detail in our upcoming videos.
Making Route Parameters Optional
Now let's see what's going to happen if we don't have this third segment, the value 2, in the URL. And then when we issue a request to our application, we see 404. Why is that? Well, if we take a look at our route template, it expects three path segments in the incoming URL: controller, action, and a value for the id parameter. At the moment, we are only passing a value for the first two path segments, controller and action, but we are not passing the value for the third path segment, which is id. So MVC does not know how to handle this incoming URL.
Now, what we want to do is make this id parameter optional. At the moment, it is mandatory. To make it optional, all we have to do is include a question mark at the end of the parameter name. Since we made this optional, the id parameter on our Details action method may or may not receive a value. If it doesn't receive a value when we call the GetEmployee method of our employer, we get an exception. In order not to get the exception, let's hard-code the value for the time being to one. We'll remove this hard-coded value in our upcoming videos. Let's save all our changes and take a look at the browser. Notice in the URL we don't have a value for id, but when I reload this page, the Details action method of our HomeController is executed, and we see the employee details. So the important point to keep in mind here is since we have made the id parameter in our route template optional, irrespective of whether we have the third path segment here (that is the value for ID) or not, the Details action method of our HomeController is executed.
Setting Default Route Values
Now let's see what's going to happen if we don't specify any of these path segments and just navigate to the root URL. Notice we get a 404. Now here is what we want the application to do. If we do not specify a value for the controller and action method in the URL, we want the application to use some defaults. We can specify those default values in the route template right here. We want the controller to default to home and the action method to default to index. With this change in place, when we reload this web page, the Index action method of our HomeController is executed, and we see the list of employees.
Conclusion and Final Review
The default route that this UseMvcWithDefaultRoute method adds to our application looks exactly similar to this route that we have configured. We can confirm that by uncommenting this, and then when I hover the mouse over, notice from the IntelliSense you can see that the default route is identical to this route. For most applications, this route template works just fine. For example, let's say we have another controller called DepartmentsController. Within this DepartmentsController, let's say we have these two action methods: List and Details. Now to get to this List action method, all we have to do is in the URL type /departments/list, and to get to the Details section, instead of list type details.
In MVC, it is the routing configuration that maps the incoming URLs to the controller action methods. The routing configuration that we have in our application at the moment is conventional routing. In addition to conventional routing, we also have attribute routing. We'll discuss that in our next video. Thank you for listening.