Previous Filters in ASP.NET Core Implementing JWT Authentication in ASP.NET Core Next

Routing in ASP.NET Core Web API

Routing in ASP.NET Core

In ASP.NET Core, routing is the process of matching incoming HTTP requests to executable endpoints in your application. It analyzes a request's URL and determines which piece of application logic, such as a controller action or a minimal API endpoint, should handle it. This system is a fundamental component of the framework and is configured in your application's middleware pipeline.

Routing is responsible for:

  • Matching the URL pattern of an incoming request.
  • Selecting the appropriate controller and action method (or endpoint).
  • Extracting route parameters from the URL.
  • Dispatching the request to the matched handler.

🔧 Example Route Template

pattern: "{controller=Home}/{action=Index}/{id?}"
  
  • controller=Home: Default controller
  • action=Index: Default action
  • id?: Optional parameter

How Routing Works in ASP.NET Core Web API

Routing in a Web API follows a pattern-matching system to direct requests to the correct controller and method. The modern approach in ASP.NET Core Web API is to use attribute routing, which defines routes directly on the controllers and their action methods using attributes.

Step-by-Step Breakdown

  1. Incoming request: A client (e.g., a web browser or JavaScript) sends an HTTP request to your API with a specific URL, like https://example.com/api/products/1.
  2. Middleware pipeline: The request enters the ASP.NET Core middleware pipeline. It first passes through UseRouting(), which adds route-matching capabilities to the pipeline.
    app.UseRouting();
    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers(); // Enables attribute routing
    });
    
    
  3. Endpoint matching: (Route Matching) The routing middleware looks at the collection of registered endpoints and attempts to find a match for the incoming URL. It considers the URL path, the HTTP method (GET, POST, PUT, DELETE), and any defined route templates.
    Attribute routes (e.g., [HttpGet("api/products/{id}")])

    Conventional routes (e.g., "api/{controller}/{action}/{id?}")
  4. Controller and action selection: The routing middleware finds a controller class with a [Route] attribute that matches the first part of the URL (e.g., api/[controller]). It then finds an action method with an attribute (e.g., [HttpGet("{id}")]) that matches the rest of the URL and the HTTP method.
  5. Route parameters: Placeholders in the route template, such as {id}, are used to extract values from the URL and passed as arguments to the selected action method.
    [HttpGet("api/products/{id}")]
    public IActionResult GetProduct(int id) { ... }
    
  6. Endpoint execution: After all middleware between UseRouting() and UseEndpoints() have run (including authorization), the UseEndpoints() middleware executes the matched endpoint.
  7. Response generation: The action method runs its logic and generates an HTTP response, typically JSON data for Web APIs.

Routing Modes in ASP.NET Core Web API

Routing Modes

Mode Description
Conventional Uses a central route template. Best for MVC apps.
Attribute Uses [HttpGet], [Route], etc. directly on actions. Preferred for APIs.
Endpoint Routing Introduced in ASP.NET Core 3.0+. Uses MapControllers() and MapGet() etc.

✅ Best Practices

  • Use attribute routing for Web APIs to keep routes close to actions.
  • Prefer route constraints (e.g., {id:int}) for clarity and validation.
  • Use versioning via route segments or headers for API evolution.
  • Keep routes RESTful: use nouns for resources, verbs via HTTP methods.

Example of Attribute Routing

[Route("api/[controller]")]
[ApiController]
public class ProductsController : ControllerBase
{
    // GET api/products
    [HttpGet]
    public IActionResult GetAllProducts()
    {
        return Ok(new string[] { "Product1", "Product2" });
    }

    // GET api/products/5
    [HttpGet("{id}")]
    public IActionResult GetProductById(int id)
    {
        return Ok($"Product with ID: {id}");
    }

    // POST api/products
    [HttpPost]
    public IActionResult CreateProduct([FromBody] Product product)
    {
        return CreatedAtAction(nameof(GetProductById), new { id = product.Id }, product);
    }
}
  

Explanation

  • [Route("api/[controller]")] sets a route prefix for the entire ProductsController. [controller] is replaced by the controller name ("Products").
  • [HttpGet] matches a GET request to /api/products.
  • [HttpGet("{id}")] matches a GET request to /api/products/5. The {id} is a route parameter passed to the method.
  • [HttpPost] matches a POST request to /api/products.

Attribute vs. Convention-Based Routing

Aspect Attribute Routing Convention-Based Routing
Configuration Defined directly on controllers and action methods using attributes. Defined centrally in the Program.cs file (or Startup.cs).
Control Offers fine-grained control over URL patterns for each action. Provides a centralized, predictable pattern for the entire application.
Readability Keeps routing information close to the code that handles the request. Requires referencing a separate configuration file.
Best suited for RESTful Web APIs using HTTP verbs and resource-based URLs. Traditional MVC apps using /{controller}/{action}/{id?} patterns.
Flexibility Highly flexible for dynamic, complex URL patterns. Can become difficult to manage for dynamic routing needs.

ASP.NET Core Request Processing Pipeline

1. What Is the Request Pipeline?

The request pipeline in ASP.NET Core is a sequence of middleware components that process incoming HTTP requests and generate responses. Each component can inspect, modify, or short-circuit the request.

2. Middleware Components

Middleware is added in Program.cs using methods like UseRouting(), UseAuthentication(), and UseEndpoints().

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
    endpoints.MapControllers();
});
  

3. How It Works Internally

  1. Request Received: The server receives an HTTP request.
  2. Middleware Execution: Each middleware runs in the order it was registered.
  3. RequestDelegate: Each middleware calls the next using await next().
  4. Endpoint Matching: Routing middleware matches the request to a controller or endpoint.
  5. Response Generation: The endpoint generates a response, which flows back through the middleware stack.

4. Middleware Example

app.Use(async (context, next) =>
{
    Console.WriteLine("Before next middleware");
    await next.Invoke();
    Console.WriteLine("After next middleware");
});
  

5. Middleware Order Matters

The order in which middleware is added affects how requests are processed. For example, UseAuthentication() must come before UseAuthorization().

6. Common Middleware

  • ExceptionHandler: Handles unhandled exceptions
  • HttpsRedirection: Redirects HTTP to HTTPS
  • StaticFiles: Serves static content
  • Routing: Matches requests to endpoints
  • CORS: Manages cross-origin requests
  • Authentication & Authorization: Secures endpoints

7. Summary

The ASP.NET Core request pipeline is a flexible and powerful system built on middleware. It allows developers to control how requests are handled, responses are generated, and services are integrated.

Back to Index
Previous Filters in ASP.NET Core Implementing JWT Authentication in ASP.NET Core Next
*