ASP.NET Core Routing
This tutorial provides an in-depth guide to understanding and implementing routing in ASP.NET Core applications. Routing is the mechanism that directs incoming browser requests to the appropriate code that handles the request.
What is Routing?
In ASP.NET Core, routing is a powerful feature that maps incoming HTTP requests to the correct handler. This handler can be a controller action, a Razor Page, or a minimal API endpoint. The routing system uses a set of rules, often defined by routes or conventions, to match the request URL to a specific piece of code.
Key Concepts in ASP.NET Core Routing
- Routes: A route is a pattern that the routing system uses to match incoming request URLs. Routes are typically defined in the
Program.cs
(orStartup.cs
) file. - Route Templates: These are strings that define the structure of a URL. They can include literal values and parameters. For example,
/Products/{id}
. - Route Constraints: These are rules applied to route parameters to ensure they match specific criteria (e.g., an ID must be an integer).
- Convention-Based Routing: A common approach where routes are defined programmatically using predefined templates and conventions.
- Attribute Routing: An approach where route information is specified directly on controller actions or Razor Pages using attributes (e.g.,
[Route("api/[controller]")]
). - MapGet, MapPost, etc.: In modern ASP.NET Core (minimal APIs), these methods are used to define routes for specific HTTP verbs.
Example: Convention-Based Routing
Here's a typical way to configure convention-based routing in ASP.NET Core:
// In Program.cs or Startup.cs (Configure method)
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
In this example:
name: "default"
: The name of the route.pattern: "{controller=Home}/{action=Index}/{id?}"
:{controller}
: Represents the controller name. If not provided, it defaults to "Home".{action}
: Represents the action name. If not provided, it defaults to "Index".{id?}
: Represents an optional parameter named "id". The?
makes it optional.
Example: Attribute Routing
Using attributes on a controller:
using Microsoft.AspNetCore.Mvc;
[ApiController]
[Route("api/[controller]")] // Base route for the entire controller
public class ProductsController : ControllerBase
{
[HttpGet] // Matches GET /api/products
public IActionResult GetAllProducts()
{
return Ok(new[] { "Product A", "Product B" });
}
[HttpGet("{id}")] // Matches GET /api/products/{id}
public IActionResult GetProductById(int id)
{
if (id == 1) return Ok($"Product {id}");
return NotFound();
}
[HttpPost] // Matches POST /api/products
public IActionResult CreateProduct([FromBody] string productName)
{
return CreatedAtAction(nameof(GetProductById), new { id = 100 }, productName);
}
}
Example: Minimal API Routing
Using extension methods for HTTP verbs:
// In Program.cs
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/", () => "Hello World!");
app.MapGet("/items", () => new[] { "Item 1", "Item 2" });
app.MapGet("/items/{id:int}", (int id) => $"Item {id}");
app.MapPost("/submit", async (HttpRequest request) =>
{
using var reader = new StreamReader(request.Body);
var body = await reader.ReadToEndAsync();
return Results.Ok($"Received: {body}");
});
app.Run();
Route Constraints
Constraints are used to limit which requests can match a route parameter. They are appended to the parameter name using a colon.
{id:int}
: Matches only integer values forid
.{slug:alpha}
: Matches only alphabetic characters.{guid:guid}
: Matches a GUID.{year:regex(\d{4})}
: Matches a 4-digit year using a regular expression.
Understanding routing is fundamental to building any web application. ASP.NET Core provides flexible options to handle request mapping effectively.
Next Steps
Explore the following topics to deepen your understanding: