Routing in ASP.NET Core MVC

Routing in ASP.NET Core MVC Application

In this article, I will discuss Routing in ASP.NET Core MVC Applications with examples. Please read our previous article discussing ASP.NET Core MVC TempData with Examples. As part of this article, we will discuss the following pointers in detail.

  1. What is Routing in ASP.NET Core MVC?
  2. How Does Routing Work in ASP.NET Core?
  3. What are the Different Types of Routing Supported by ASP.NET Core MVC?
  4. What is Conventional Based Routing in ASP.NET Core MVC Web Application?
  5. What is Attribute-Based Routing in ASP.NET Core MVC Application?
  6. Understanding Conventional-Based Routing in ASP.NET Core MVC.
  7. Understanding the Default Route in ASP.NET Core MVC Web Application.
  8. Understanding Route Template in ASP.NET Core MVC Application.
  9. Configure Multiple Conventional Routing in ASP.NET Core MVC Application.
  10. Advantages and Consideration of Conventional Routing.
What is Routing in ASP.NET Core MVC?

Routing in the ASP.NET Core MVC Web Application is a mechanism that will inspect the incoming HTTP requests (i.e., URLs) and then map that HTTP request to the controller’s action method. This mapping is done by the routing rules which are defined for the application. We can do this by adding the Routing Middleware to the Request Processing Pipeline.

You can configure multiple routes for your application, and for each route, you can also set some specific configurations such as default values, constraints, etc. If this is not clear at the moment, then don’t worry; we will discuss each and everything with examples.

How Does Routing Work in ASP.NET Core?

So, in simple words, we can say that Routing is a pattern-matching system that monitors the incoming request and figures out what to do with that request. Typically, it is a way to serve the user’s request. For a better understanding, please have a look at the following diagram.

When the client makes a request, i.e., an HTTP Request, then that request is first received by the routing engine. Once the Routing engine receives an HTTP Request, the Routing system tries to find out the matching route pattern of the requested URL with already registered routes. Routes contain information about the Controller name, action method name, method type (Get, Post, Put, Patch, Delete), method parameters, route data, etc.

If it finds a matching URL pattern for the incoming request, then it forwards the request to the appropriate controller and action method. If no match for the incoming HTTP request URL Pattern is found, it returns a 404 HTTP status code to the client. For a better understanding, please have a look at the following diagram.

What are the Different Types of Routing Supported by ASP.NET Core MVC?

We can configure routes in the ASP.NET Core MVC Web Application in two ways. They are as follows:

  1. Convention-Based Routing
  2. Attribute-Based Routing.
What is Conventional Based Routing in ASP.NET Core MVC Web Application?

In Conventional Routing, the route is determined based on the conventions defined in the Routing Middleware, which will map the incoming HTTP Requests (i.e., URLs) to controller action methods. Before .NET 6, the Convention Routes are defined within the Configure method of the Startup class. From .NET 6, you can configure the Convention Based Routes within the Main method of the Program class.

Conventional routing was the original routing approach used in ASP.NET Core MVC. It uses a predefined URL pattern to determine which controller and action method to execute. This pattern is defined in the Program.cs file and typically specifies placeholders for the controller and action names.

  • Configuration: It is defined globally in the application’s startup configuration, meaning that the routing rules are applied universally.
  • Usage: This approach is useful for applications with a clear and simple URL structure, where the URLs follow a consistent pattern.
  • Example: Defining a route pattern like {controller=Home}/{action=Index}/{id?} would match a URL like /Products/Details/5 and map it to the Details action on the Products controller with 5 as an action parameter.
What is Attribute-Based Routing in ASP.NET Core MVC Application?

Attribute Routing in ASP.NET Core MVC is a powerful approach to defining URL routes by using Route Attributes directly on controller actions or controllers themselves. With Attribute-Based Routing, you can specify the routing configuration at a very granular level, making routing logic more explicit and closely tied to action methods. This approach provides a way to explicitly specify the route for each controller and action.

  • Configuration: Routes are defined using attributes on controllers and action methods. This means each controller or action can have its own routing defined, making it easier to understand and maintain the routing rules.
  • Usage: This is particularly useful for complex URL structures and APIs or when you need routes that don’t easily fit into a conventional pattern.
  • Example: Using [Route(“products/details/{id}”)] on an action method would map the specific URL /products/details/5 to that action.
Combining Conventional and Attribute Routing

Combining conventional and attribute routing in the same application is possible. This can balance the simplicity of conventional routing for general URL patterns and the flexibility of attribute routing for specific or complex URLs. However, care should be taken to avoid route conflicts and ensure the URL is clearly understood and well-defined.

In this article, we will discuss Conventional Routing, and in our upcoming articles, we will discuss Attribute-Based Routing in ASP.NET Core MVC Applications.

Understanding Conventional-Based Routing in ASP.NET Core MVC:

Conventional routing is often used for applications with a clear and hierarchical URL structure. It enables developers to define routing rules in a centralized location, typically within the Program.cs file that makes managing and understanding the URL structure easier, especially for large applications.

That means conventional routing uses routes defined in the Program.cs file. These routes map URL paths to controller actions. When the application receives a request, the routing middleware parses the URL and matches it to one of the defined routes. If a match is found, the corresponding controller action is invoked.

In the ASP.NET Core MVC Web Application, the controller action method will handle the incoming HTTP Requests, i.e., URLs. For example, if we issue a request to the /Home/Index URL, then the Index action method of the Home Controller class will handle the request, as shown in the image below.

Conventional Based Routing in ASP.NET Core MVC

Similarly, if we issue a request to the /Home/Details/2 URL, then the Details action method of the Home Controller class will handle the request, as shown in the image below. Here, the parameter value 2 is automatically mapped to the id parameter of the Details action method.

Conventional Routing in ASP.NET Core MVC

Now, the question that should come to your mind is, we have not explicitly defined any routing rules for the application. Then how is this mapping done, i.e., how is the /Home/Index URL mapped to the Index action method, and how is the /Home/Details/2 URL mapped to the Details action method of the Home Controller class? This is done by the MVC Routing Middleware Component, which we registered into the Request Processing Pipeline application. 

Understanding Routing in ASP.NET Core MVC Application:

So, first, create an ASP.NET Core Application using the ASP.NET Core Model-View-Controller Template. To create an ASP.NET Core Web Application with the Model-View-Controller Project template. First, open Visual Studio 2022 and click the Create a new project tab, as shown in the image below.

Understanding the Default Route in ASP.NET Core MVC Application

Once you click on the Create a new Project tab, it will open the following Create a new Project window. From this window, select C#, All Platforms, and Web from the respective dropdowns as highlighted below. Select ASP.NET Core Web App (Model-View-Controller) as highlighted below, and click the Next button, as shown in the image below.

Understanding the Default Route in ASP.NET Core MVC Application

Once you click on the Next button, it will open the Configure Your New Project window. Here, you need to provide the necessary information to create a new ASP.NET Core project. First, give an appropriate name for your project (RoutingInASPDotNetCoreMVC), set the location where you want to create this project, and the solution name for the ASP.NET Core Web application. And finally, click on the Create button, as shown in the image below.

Understanding the Default Route in ASP.NET Core MVC Application

Once you click on the Next button, it will open the following Additional Information window. Here, you need to select Framework – .NET 6.0 (Long-term support), Authentication type – None. You also need to check the Configure for HTTPS and do not use top-level statements check boxes. Finally, click on the Create button, as shown in the image below.

Understanding the Default Route in ASP.NET Core MVC Application

Once you click on the Create Button, the project will be created with the Model-View-Controller template with the following folder and file structure.

Understanding the Default Route in ASP.NET Core MVC Application

Understanding the Default Route in ASP.NET Core MVC Web Application:

As we created the project with a Model-View-Controller template, the required MVC Services and MVC Middleware components are, by default, added to the Request Processing Pipeline. So, if you open the Program class, then you will find the following code.

namespace RoutingInASPDotNetCoreMVC
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var builder = WebApplication.CreateBuilder(args);

            // Add services to the container.
            builder.Services.AddControllersWithViews();

            var app = builder.Build();

            // Configure the HTTP request pipeline.
            if (!app.Environment.IsDevelopment())
            {
                app.UseExceptionHandler("/Home/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseStaticFiles();

            app.UseRouting();

            app.UseAuthorization();

            app.MapControllerRoute(
                name: "default",
                pattern: "{controller=Home}/{action=Index}/{id?}");

            app.Run();
        }
    }
}

As you can see in the above code, MVC services are added by the following statement.

builder.Services.AddControllersWithViews();

Routing Middleware Components are added by using the UseRouting and MapControllerRoute methods. Further, if you notice the MapControllerRoute, then you will see the following.

Understanding Routing in ASP.NET Core MVC Application

The default route is created with the following URL Pattern. So, if we don’t specify anything in the URL, then by default, the Index action method of the Home Controller class will handle the request.
{controller=Home}/{action=Index}/{id?}

In this example, the MapControllerRoute method defines a default route. The pattern parameter specifies the route template, where {controller}, {action}, and {id} are placeholders for route parameters. The name parameter gives the route a name, which can be used for generating URLs. Here’s a breakdown of the placeholders:

  • {controller}: Represents the name of the controller class.
  • {action}: Represents the action method’s name within the controller.
  • {id?}: Represents an optional route parameter called “id”.

With this configuration, an incoming URL like /Home/Index would match the Index action method of the HomeController. Similarly, /Products/Details/5 would match the Details action method of the ProductsController with an id parameter set to 5.

You can customize routing further by adding additional routes, using attribute routing, and applying constraints to route parameters. Attribute routing allows you to define routes directly on your action methods or controllers using attributes, providing more control over how URLs are mapped.

Understanding Route Template in ASP.NET Core MVC Application:

As we see, the default route is created with the URL Pattern: {controller=Home}/{action=Index}/{id?}
So, the above default route template will map most URLs with the following pattern.
http://localhost:52190/Home/Details/2

  1. The first segment path of the URL, i.e., /Home, is mapped to the HomeController. As you can see in the URL, we do not have the word Controller with the first segment path of the URL. But it maps to the HomeController because when ASP.NET Core MVC Framework finds the word /Home as the first segment path of the URL, it internally appends the word Controller.
  2. The second segment path of the URL, i.e., /Details, is mapped to the Details(int id) action method of the HomeController class.
  3. The third segment path of the URL, i.e., 2, is mapped to the id parameter of the Details(int id) action method.

As you can see in the default route template {controller=Home}/{action=Index}/{id?}, we have a question mark at the end of the id parameter, which makes the id parameter optional. That means the following two requests now map to the same Details action method of the Home Controller class.
/Home/Details/1
/Home/Details

In the default route template {controller=Home}/{action=Index}/{id?}, the value Home in {controller=Home} is the default value for the Controller. Similarly, the value Index in {action=Index} is the default value for the action method. That means if we navigate to the application’s root URL, as shown below, then that request will be handled by the Index action method of the Home Controller class.
http://localhost:52190

The following two URLs are also mapped to the Index action method of the HomeController class.
http://localhost:52190/Home
http://localhost:52190/Home/Index

The default route works fine for most of the ASP.NET Core MVC Web Applications. For example, create a Controller named StudentController and then copy and paste the following code into it.

using Microsoft.AspNetCore.Mvc;
namespace RoutingInASPDotNetCoreMVC.Controllers
{
    public class StudentController : Controller
    {
        public string Index()
        {
            return "Index() Action Method of StudentController";
        }
        public string Details(int? id)
        {
            return $"Details({id}) Action Method of StudentController";
        }
    }
}

Now, the URL /student/index is mapped to the Index() action method of the StudentController class, and the URL /student/details or /student/details/5 both are mapped to the Details(int? id) action method of the StudentController

Configure Multiple Conventional Routing in ASP.NET Core MVC Application

Configuring multiple conventional routes in an ASP.NET Core MVC application involves defining multiple route patterns that the application can use to handle incoming requests and map them to the appropriate controllers and actions. This is done in the Program.cs file of your ASP.NET Core project. For example, we want to access the Index Action Method of the Student Controller using the following URL.
https://localhost:44359/Student/All
To achieve this, we can configure the MapControllerRoute method, as shown in the below image. Here, you can see we have specified the pattern as Student/All and specified the default controller and action name as controller = Student, action = Index.

Can we configure Multiple Conventional Based Routing in ASP.NET Core MVC Application

Next, we want to access the Details Action Method of the Student Controller using the following URL.
https://localhost:44359/StudentDetails/10
To achieve this, we can configure another MapControllerRoute method, as shown in the below image. Here, you can see we have specified the pattern as StudentDetails/{ID} and specified the default controller and action name as controller = Student”, action = Details.

Configure Multiple Conventional Based Routing in ASP.NET Core MVC Application

For the rest of the controller and actions, we need to access them using the following URL Pattern. Along with we also need to configure the default controller and action name as Home and Index.
https://localhost:44359/{Controller Name}/{Action method Name}
To achieve this, we can configure another MapControllerRoute method, as shown in the below image. Here, you can see we have specified the pattern as {controller}/{action}/{id:int?} and specified the default controller and action name as controller = Home, action = Index.

Routing in ASP.NET Core MVC

The complete code of the Program class is given below.

namespace RoutingInASPDotNetCoreMVC
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var builder = WebApplication.CreateBuilder(args);

            // Add services to the container.
            builder.Services.AddControllersWithViews();

            var app = builder.Build();

            // Configure the HTTP request pipeline.
            if (!app.Environment.IsDevelopment())
            {
                app.UseExceptionHandler("/Home/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseStaticFiles();

            app.UseRouting();

            app.UseAuthorization();

            //https://localhost:44359/Student/All
            app.MapControllerRoute(
                name: "StudentAll",
                pattern: "Student/All",
                defaults: new { controller = "Student", action = "Index" }
            );

            //https://localhost:44359/StudentDetails/10
            app.MapControllerRoute(
                name: "StudentIndex",
                pattern: "StudentDetails/{ID}",
                defaults: new { controller = "Student", action = "Details" }
            );

            //For Rest of the Controller Actions including the Default Home Controller Index
            app.MapControllerRoute(
                name: "default",
                pattern: "{controller}/{action}/{id:int?}",
                defaults: new { controller = "Home", action = "Index" }
            );

            app.Run();
        }
    }
}
Points to Remember While Defining Multiple Conventional Routing
  • Route Order Matters: Routes are evaluated in the order they are defined. Ensure the most specific routes are defined first, as a request will be handled by the first route it matches.
  • Naming Routes: It’s a good practice to give each route a unique name. This helps when generating URLs based on route names.
  • Defaults: You can specify controller, action, and parameter default values. This is useful for defining fallbacks for missing parts of the route.
  • Constraints: Routes can also have constraints (e.g., {id:int}) to limit what values can be matched by a parameter.

With the above changes in place, run the application and navigate to the specific URLs, and you will get the data as expected.

Advantages of Conventional Routing
  • Centralized Configuration: It provides a centralized location to manage URL routing rules, making it easier to understand and manage the application’s URL structure.
  • URL Generation: It simplifies the generation of URLs, allowing you to use routing names and parameters to generate URLs without hard-coding them. This is useful for generating links in views.
  • Clear URL Structure: It encourages a clear and hierarchical URL structure, which can improve the discoverability of URLs and make them more intuitive.
Considerations

While conventional routing is powerful and flexible, it has some considerations:

  • Complexity for Dynamic URLs: For applications that require dynamic URL patterns, conventional routing can become complex and hard to manage.
  • Routing Conflicts: Improper configuration can lead to routing conflicts where multiple routes match a URL, leading to unexpected behavior.

In the next article, I will discuss Custom Route and Route Constraints, Optional Parameters, and Default Values in the ASP.NET Core MVC application. In this article, I explain the fundamentals of Routing in ASP.NET Core MVC Applications. I hope you enjoy this article.

6 thoughts on “Routing in ASP.NET Core MVC”

  1. “The second segment path of the URL i.e. “/Details” is mapped to the “Details(int id)” action method of the HomeController” – This is not Home controller, but Student controller.

Leave a Reply

Your email address will not be published. Required fields are marked *