C# tutorials > Frameworks and Libraries > ASP.NET Core > Routing in ASP.NET Core (attribute routing, conventional routing)

Routing in ASP.NET Core (attribute routing, conventional routing)

Routing is a crucial aspect of ASP.NET Core applications, responsible for mapping incoming requests to the appropriate controller actions. ASP.NET Core offers two primary approaches to defining routes: conventional routing and attribute routing. Understanding the differences and advantages of each approach is essential for building well-structured and maintainable web applications.

Introduction to Routing in ASP.NET Core

Routing is the process of matching incoming HTTP requests to controller actions. It determines which controller and action method should handle a particular request based on the URL. ASP.NET Core provides a flexible routing system that can be configured in various ways.

Conventional Routing

Conventional routing defines routes using a pattern. The most common pattern is the 'default' route, which follows the structure {controller}/{action}/{id?}. This route maps requests based on the controller and action names derived from the URL. The id? parameter is optional.

In the example code, endpoints.MapControllerRoute configures the default route. If a request comes in for /Products/Details/5, the ProductsController's Details action method will be executed, and the id parameter will be set to 5.

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

Concepts Behind Conventional Routing

  • Convention-Based: Relies on established conventions for controller and action names.
  • Centralized Configuration: Routes are defined in a central location, typically within the Startup.cs file.
  • Order Matters: The order in which routes are defined is significant. The first route that matches the request will be used.

Attribute Routing

Attribute routing uses attributes to define routes directly on controllers and action methods. This provides a more granular and localized approach to routing configuration.

In the example, the [Route("products/{id:int}")] attribute on the ProductsController defines a base route for all actions within that controller. The [HttpGet("details")] attribute on the Details action method specifies that it should handle GET requests to /products/{id}/details. The :int constraint ensures the `id` is an integer. To enable attribute routing, you must call `endpoints.MapControllers()` in your `Startup.cs`.

[Route("products/{id:int}")]
public class ProductsController : Controller
{
    [HttpGet("details")]
    public IActionResult Details(int id)
    {
        // ...
        return View();
    }
}

Enabling Attribute Routing

To use attribute routing, you need to call the MapControllers() method within the UseEndpoints method in your Startup.cs file. This tells ASP.NET Core to discover and register routes defined using attributes on controllers and actions.

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllers();
    //OPTIONAL: if you also want to use conventional routing, keep the following line
    //endpoints.MapControllerRoute(name: "default", pattern: "{controller=Home}/{action=Index}/{id?}");
});

Concepts Behind Attribute Routing

  • Attribute-Driven: Routes are defined using attributes placed directly on controllers and actions.
  • Localized Configuration: Routing configuration is located alongside the corresponding controller logic.
  • More Flexible: Offers more control over route patterns and constraints.

Real-Life Use Case: E-commerce Application

In an e-commerce application:

  • Conventional Routing: Could be used for basic product listing and category pages (e.g., /Products/List, /Categories/Browse).
  • Attribute Routing: Would be ideal for specific product details pages with complex route patterns (e.g., /products/{category}/{productName}-{productId:int}).

Best Practices

  • Choose the Right Approach: Consider the complexity of your application and the granularity of control required when selecting between conventional and attribute routing.
  • Use Route Constraints: Employ route constraints (e.g., :int, :bool) to ensure that routes match the expected data types.
  • Maintain Consistency: Adopt a consistent routing strategy throughout your application to improve maintainability.
  • Combine Approaches: You can combine both conventional and attribute routing in the same application. Attribute routing is generally preferred for more specific and complex routes, while conventional routing can handle simpler scenarios.

Interview Tip

Be prepared to discuss the pros and cons of conventional and attribute routing, and provide examples of when you would use each approach. Demonstrate your understanding of route constraints and how they can be used to validate route parameters.

When to use them

Conventional Routing: Best suited for simple, standard routing patterns (e.g., the default {controller}/{action}/{id?} pattern). It's easy to set up and maintain for basic applications.

Attribute Routing: Ideal for more complex routes, RESTful APIs, and scenarios where you need fine-grained control over route definitions. It provides better code locality and reduces the need for large, centralized route configuration files.

Pros of Conventional Routing

  • Simple to set up and understand for basic routing needs.
  • Centralized configuration makes it easy to see all routes in one place.

Cons of Conventional Routing

  • Can become cumbersome for complex applications with many routes.
  • Lacks the flexibility of attribute routing for defining custom route patterns.
  • Routing logic is separated from the controller code.

Pros of Attribute Routing

  • More flexible and expressive for defining complex routes.
  • Routing logic is located alongside the controller code, improving code locality.
  • Supports route constraints and custom route patterns.

Cons of Attribute Routing

  • Can lead to more verbose code, especially for simple routes.
  • Requires more effort to set up initially compared to conventional routing.

Alternatives

While conventional and attribute routing are the primary methods, other alternatives or complementary techniques exist:

  • Custom Route Handlers: For highly specialized routing needs, you can create custom route handlers that implement the IRouteHandler interface.
  • Endpoint Routing: The underlying mechanism that both conventional and attribute routing use. Direct manipulation of endpoint metadata is possible, though less common.

FAQ

  • What happens if I have both conventional and attribute routes defined for the same action?

    Attribute routes take precedence over conventional routes. If an action method has an attribute route defined, it will be matched before any conventional routes are considered.

  • How do I define optional parameters in attribute routes?

    You can define optional parameters using a question mark (?) after the parameter name in the route template. For example, [Route("products/{id:int?}")] makes the id parameter optional.

  • Can I use regular expressions in route constraints?

    Yes, you can use regular expressions in route constraints to define more complex matching rules. For example: [Route("articles/{articleId:regex(^[[a-zA-Z0-9-]]+$)}")].