Routing in ASP.NET Core Web API

Routing in ASP.NET Core Web API Application

In this article, I will discuss Routing in ASP.NET Core Web API Applications. Please read our previous article discussing Models in ASP.NET Core Web API Applications. 

What is Routing in ASP.NET Core?

Let us understand Routing in ASP.NET Core Web API Application with an example. Please have a look at the following image. On the right-hand side, we have the server, and within the server, we have deployed our ASP.NET Core Web API application. Inside the ASP.NET Core Web API Application, assume we have three controllers, each containing some action methods. On the left-hand side, we have the clients. The client can be a Web Browser, Postman, Fiddler, Swagger, IoTs, Mobile APP, Desktop Application, etc.

Suppose we are sending a request from the client to the server. As we already discussed, the request must go through the Request Processing Pipeline. If everything is fine, then the ASP.NET Core Framework navigates that request to the controller action method. Then, the controller action method handles that request, generates the response, and then the generated response is sent back to the client who initially made the request.

What is Routing in ASP.NET Core?

Here, we need to understand how the application will come to know which request will be mapped to which controller action method. Basically, the mapping between the URL and resource (controller action method) is nothing but the concept of Routing.

So, Routing in ASP.NET Core Web API is a concept that maps incoming HTTP requests to specific controllers and actions in your application. It determines how the Web API handles an HTTP request.

How Does the Routing Work in ASP.NET Core Web API?

Routing in ASP.NET Core Web API application is the process of mapping the incoming HTTP Request (URL) to a particular resource, i.e., controller action method. Here is an overview of How Routing works in ASP.NET Core Applications:

  • Configuration of Routing: In ASP.NET Core, routing is configured in the Program.cs file. We need to register the required Web API services to the dependency injection container, and then we need to configure the Routing Middleware to the Request Processing Pipeline.
  • Route Templates: Each controller action method can be decorated with route attributes defining the templates. These templates specify the URL patterns that the action will handle. The most commonly used attributes are [Route], [HttpGet], [HttpPost], [HttpPut], and [HttpDelete]. The templates can include various segments and parameters (like IDs) that are used to pass data to the controller methods.
  • Route Matching: When a request is made to the Web API, the routing middleware parses the URL and tries to match it against the defined route templates. The matching process considers the HTTP method (GET, POST, etc.), the URL path, and any constraints defined in the route template.
  • Parameter Binding: Once a route is matched, any parameters in the route are bound to the action method’s parameters. ASP.NET Core automatically handles the conversion of URL segments to the appropriate method parameter types.
  • Middleware Pipeline: If a match is found, the request is forwarded through the middleware pipeline until it reaches the appropriate controller action. If no match is found, the framework can return a 404 Not Found response or forward the request to another middleware for further processing.
  • Attribute Routing vs. Conventional Routing: ASP.NET Core supports two types of routing: Attribute Routing (where routes are defined above actions or controllers using Route Attributes) and Conventional Routing (where routes are defined in a central location, typically in Program.cs class file). Attribute Routing provides more control and is commonly used in ASP.NET Core Web API projects.
  • Routing Constraints: Constraints can be applied to route parameters to restrict the type of data that matches a particular parameter. For example, you can specify that a certain URL segment must be an integer.

Note: We can access any resource using a unique URL. It is also possible that a resource can have multiple unique URLs. However, multiple resources cannot have the same URL, and if you do so, then the application gets confused about which action method to invoke. As a result, you will get an ambiguity error.

Example to Understand Routing in ASP.NET Core Web API:

If you create the Project using the ASP.NET Core Web API template, then by default, it will add the required services and Routing middleware components. So, we will create an ASP.NET Core Empty project and then manually configure the routing middleware to the request processing pipeline.

So, create an Empty ASP.NET Core Application by following the below steps. First, open Visual Studio 2022 and click the Create a new project option, as shown in the image below.

Example to Understand Routing in ASP.NET Core Web API

Once you click on the Create a new project option, it will open the following Create a new project window. From this window, select the ASP.NET Core Empty Project template, which uses the programming language as C#, and finally, click on the Next button as shown in the image below.

Example to Understand Routing in ASP.NET Core Web API

Once you click on the Next button, it will open configure your new project window. Here, you need to specify the Project name (RoutingInASPNETCoreWebAPI) and the location where you want to create the project. Then, click on the Next button, as shown in the image below.

How Does the Routing Work in ASP.NET Core Web API?

Once you click on the Next button, it will open the Additional Information window. Please make sure to select the Target Framework as .NET 8, check the Configure for HTTPS, and do not use top-level statement checkboxes and click on the Create button, as shown in the image below.

How Does the Routing Work in ASP.NET Core Web API?

Once you click on the Create button, it will create the ASP.NET Core Empty Project with the following file and folder structure.

How Does the Routing Work in ASP.NET Core Web API?

Configuring ASP.NET Core Web API Service:

Let us add the ASP.NET Core Web API services to the dependency injection container so that our application will support the ASP.NET Core Web API Features. We need to configure the required Web API services within the Program class. So, add the following code within the Program.cs class file:

builder.Services.AddControllers();

Configuring the Routing Middlewares in ASP.NET Core:

To enable Routing in ASP.NET Core, we must add the following two middleware components to the HTTP Request Processing Pipeline.

app.UseRouting();
app.MapControllers();

In .NET 8, app.UseRouting() and app.MapControllers() are used within the context of an ASP.NET Core application to configure routing and controller endpoints.

  • app.UseRouting(): This middleware enables routing capabilities in your ASP.NET Core application. It is responsible for matching incoming HTTP requests to routes that have been defined in your application. UseRouting should be added to the middleware pipeline before any middleware that requires knowledge of the requested endpoint, like authorization or endpoint-specific middleware.
  • app.MapControllers(): This extension method is used to map attribute-routed controllers. It essentially tells the application to look for controllers in your project and creates routes for them based on the attributes you’ve defined (like [Route], [HttpGet], etc.). This is typically used when you have an API-centric application with controllers handling various HTTP requests. 

In the ASP.NET Core Application, we have two ways to define the Routing, i.e., Conventional and Attribute-Based Routing. Attribute Routing is the most preferred way of defining routes in ASP.NET Core Web API Applications; hence, we will only focus on Attribute Routing in this course. But we will also discuss Conventional Routing.

Adding Controller:

We have added the ASP.NET Core Web API Service and set the Routing for our application. Now, let us add a controller, i.e., EmployeeController, to our application. The Controllers in the ASP.NET Core Application should be added to your project’s Controllers folder. So, let us first add the Controllers folder to the project root directory.

Let’s add the Home Controller within the Controllers folder. To do so, right-click on the Controllers folder and then select Add => Controller from the context menu, which will open the following Add New Scaffolded item window. From the left side, select API, and from the middle pane, select API Controller – Empty and click on the Add button, as shown in the image below.

Configuring the Routing Middlewares in ASP.NET Core

From the next window, provide the Controller name as EmployeeController and click the Add button, as shown in the image below.

Adding Controller

Once you click on the Add button, it will add a class file with the name EmployeeController.cs within the Controllers folder. The following default code is inside the EmployeeController.cs class file.

Adding Controller

Adding Attribute Routing in ASP.NET Core Web Application:

Now, let us add two action methods within the EmployeeController class. Now, please don’t concentrate on the return type and the data that we are returning from the action method; rather, concentrate on the Routing concept.

We want to invoke the GetAllEmployees method with the URL /Emp/All and the GetEmployeeById method with the URL /Emp/ById/102. To achieve this, we need to use the Route Attribute and decorate the action GetAllEmployees and GetEmployeeById method as [Route(“Emp/All”)] and [Route(“Emp/ById/{Id}”)] respectively. So, modify the EmployeeController class as shown below.

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

namespace RoutingInASPNETCoreWebAPI.Controllers
{
    [ApiController]
    public class EmployeeController : ControllerBase
    {
        [Route("Emp/All")]
        [HttpGet]
        public string GetAllEmployees()
        {
            return "Response from GetAllEmployees Method";
        }

        [Route("Emp/ById/{Id}")]
        [HttpGet]
        public string GetEmployeeById(int Id)
        {
            return $"Response from GetEmployeeById Method Id: {Id}";
        }
    }
}

Note: If we don’t specify the action method type, then by default, it will be HttpGet. But, if you don’t decorate the action method with an HTTP verb, your application will work as expected, but Swagger will not work. So, here, we are explicitly specifying the HTTP verbs.

Now everything is ready. So, run the application and access the action method using the URL we configured, as shown in the below image.

Adding Attribute Routing in ASP.NET Core Web Application

RouteAttribute in ASP.NET Core:

The RouteAttribute class is used to define the routing configuration for controller actions. The RouteAttribute specifies URLs that can be used to access a controller action. It allows you to define custom and more readable URLs that are not strictly tied to the names of the controllers and actions.

You can apply the RouteAttribute to a controller or an action method. When applied to a controller, it defines a common route prefix for all action methods in that controller. When applied to an action method, it specifies the route for that specific action. Let us have a look at the signature of the Route Attribute. The following image shows the definition of the Route Attribute.

RouteAttribute in ASP.NET Core

As you can see in the above image, Route Attribute is basically a class inherited from the Attribute class and IRouteTemplateProvider interface. The Constructor of the RouteAttribute class takes the template as an input parameter, which is nothing but the URL you accept from the client and cannot be null. The meaning of the Properties of Route Attribute class is as follows:

  • Name: This property retrieves the route’s name, which can be used for generating links using a specific route.
  • Order: It defines the order of route execution, with lower values indicating higher priority. The default value, if not specified, is 0.
  • Template: This property holds the route template and can be null.
Conventional Routing in ASP.NET Core Web API:

If you want to use Conventional Routing, please add the MapControllerRoute middleware component to the Program.cs class file. Here, we are configuring the Route Pattern as api/{controller}/{action}/{id?} where id is the optional parameter.

app.MapControllerRoute(
    name: "default",
    pattern: "api/{controller}/{action}/{id?}");
Modifying the Employee Controller:

Next, modify the Employee Controller as follows. Here, we are removing the Route Attribute from the Controller action methods. You must also remove the ApiController attribute, which is decorated with the Controller class. This is because the ApiController attribute will force the action method to use the Route attribute.

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

namespace RoutingInASPNETCoreWebAPI.Controllers
{
   // [ApiController]
    public class EmployeeController : ControllerBase
    {
        // [Route("Emp/All")]
        [HttpGet]
        public string GetAllEmployees()
        {
            return "Response from GetAllEmployees Method";
        }

        //  [Route("Emp/ById/{Id}")]
        [HttpGet]
        public string GetEmployeeById(int Id)
        {
            return $"Response from GetEmployeeById Method Id: {Id}";
        }
    }
}

With the above changes in place, you can access the APIs using /api/Employee/GetAllEmployees and /api/Employee/GetEmployeeById/103 URL, as shown below.

Conventional Based Routing in ASP.NET Core Web API

Can we use both Convention-based and Attribute-based Routing in ASP.NET Core Web API?

Yes, we can use both conventional and attribute-based Routing in ASP.NET Core Web API Applications. The action method that is decorated with a Route Attribute will use Attribute Routing, and the action method without the Route Attribute will use Conventional Routing. For a better understanding, please modify the Employee Controller as follows:

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

namespace RoutingInASPNETCoreWebAPI.Controllers
{
   // [ApiController]
    public class EmployeeController : ControllerBase
    {
        [Route("Emp/All")]
        [HttpGet]
        public string GetAllEmployees()
        {
            return "Response from GetAllEmployees Method";
        }

        //  [Route("Emp/ById/{Id}")]
        [HttpGet]
        public string GetEmployeeById(int Id)
        {
            return $"Response from GetEmployeeById Method Id: {Id}";
        }
    }
}

As you can see in the above code, now we can access the GetAllEmployees method using the Attribute Routing, i.e., /Emp/All URL, and we can access the GetEmployeeById action method using the Conventional Routing, i.e., /api/employee/GetEmployeeById/102 URL as shown in the below image:

Can we use both Convention-based and Attribute-based Routing in ASP.NET Core Web API?

What is ApiController Attribute in ASP.NET Core Web API?

The ApiController attribute in ASP.NET Core Web API plays a significant role in developing HTTP API projects. It was introduced in ASP.NET Core 2.1 and provides several features that make building robust and well-documented web APIs easier. When you apply this attribute to a controller class, it enables various API-specific behaviors and conventions. Here are some key aspects of the ApiController attribute:

  • Attribute Routing Requirement: The ApiController attribute makes attribute routing a requirement. This means you must use the Route attribute to define the routes. Controllers marked with this attribute won’t be accessible through conventional routing.
  • Automatic HTTP 400 Responses: Model validation errors automatically trigger an HTTP 400 response, which is a big change from earlier versions, where you had to manually check ModelState.IsValid and return a bad request.
  • Binding Source Parameter Inference: The attribute enables the inference of the source of the binding for action parameters. For instance, if you have a complex type parameter, the ASP.NET Core runtime assumes it’s from the request body. The runtime assumes simple types come from the route data or query string.
  • Problem Details for Error Status Codes: When using the ApiController attribute, the framework automatically formats the response for types of errors (like 404 Not Found) into a standardized format (ProblemDetails), which is more helpful and descriptive.
  • Required Attribute on Non-Nullable Parameters: Parameters that are non-nullable are assumed to be required, and if a null value is passed, the API will automatically return a 400 Bad Request.
  • Support for OpenAPI (Swagger) Documentation: This attribute also facilitates the generation of OpenAPI (Swagger) documentation, as it provides additional metadata that can be useful for generating more descriptive API documentation.
Convention vs Attribute Routing in ASP.NET Core Web API

In ASP.NET Core Web API, routing is a fundamental concept that determines how HTTP requests are matched to the actions on controllers. There are two primary approaches to routing: Convention-based routing and Attribute routing. Both have their own advantages and use cases.

Convention-based Routing

Convention-based routing defines routes based on a set of conventions specified in the Program.cs file. Here, routes are defined globally for the application.

Advantages:
  • Centralized Configuration: All routes are defined in one place, making it easier to see the big picture of the URL structure of your API.
  • Consistency: By following conventions, the routes across different controllers and actions are consistent.
Disadvantages:
  • Less Flexible: It is harder to define complex and custom routes that deviate from the established conventions.
  • Refactoring Challenges: Changing controller or action names can break routes if not updated in the routing configuration.
Use Cases:
  • It is best for applications with a straightforward and uniform URL structure.
  • When you want a centralized place to manage routing.
Attribute Routing

Attribute routing uses attributes to define routes directly on controllers and actions. This approach provides more control by allowing custom and complex routes for each action.

Advantages:
  • High Flexibility: Enables defining custom routes per action, allowing for complex URL structures.
  • Self-documenting: Routes are defined where the action is defined, making it clear what URL maps to what action.
  • Support for HTTP Verb Constraints: Easily specify HTTP methods (GET, POST, etc.) for actions.
Disadvantages:
  • Scattered Configuration: Routes are spread across controllers and actions, making it harder to get an overview of the API’s URL structure.
  • Potential for Duplication: There is a possibility of duplicating route patterns, leading to conflicts or confusion.
Use Cases:
  • Ideal for APIs with complex and non-uniform URL patterns.
  • When you need fine-grained control over the routing of each action.
  • Useful for versioning APIs by including the version in the route.

In the next article, I will discuss Working with Variables and Query Strings in Routing with Examples. In this article, I explain Routing in ASP.NET Core Web API Applications, how the Routing mechanism works, and how to configure Routing in ASP.NET Core Web API Applications with Examples. I hope you enjoy this Routing in ASP.NET Core Web API Applications article.

6 thoughts on “Routing in ASP.NET Core Web API”

Leave a Reply

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