Mastering API Routing and Controllers in ASP.NET

Rafael Araujo de Lima
3 min readNov 28, 2024

--

Source: https://moien.dev/

When interacting with API endpoints, we often need to send authentication, authorization, and task-specific data. Applications usually have multiple endpoints, each serving a specific purpose — login, loading page data, processing payments, etc. For each endpoint, it’s crucial to evaluate its functionality, the required data, and how this data will be provided.

Routing and Controllers

In ASP.NET, we can map routes to controllers using attribute-based routing. Below is a basic example of how to configure this in the Program.cs file:

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

app.UseRouting(); // Adds routing middleware to the pipeline
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers(); // Enables attribute-based controller routing
});

app.Run();

Attribute-Based Routing

Define your routes directly in the controllers:

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

[HttpGet("{id}")]
public IActionResult GetById(int id)
{
return Ok($"Product {id}");
}
}
  • [Route("api/[controller]")]: Sets the base route for the controller. The [controller] token dynamically replaces the controller name.
  • [HttpGet]: Specifies the HTTP method supported by the action.
  • [HttpGet("{id}")]: Adds a route parameter (id), accessible via URLs like /api/products/1.

Generated URLs:

  • GET /api/products → Maps to GetAll.
  • GET /api/products/1 → Maps to GetById.

Dynamic Tokens in Routing

You can dynamically replace tokens in routes:

  • [controller]: The controller name without the "Controller" suffix.
  • [action]: The method name.
  • [area]: The area name (used with areas).
[Route("api/[controller]/[action]")]
[ApiController]
public class OrdersController : ControllerBase
{
[HttpGet]
public IActionResult List()
{
return Ok("Listing orders");
}

[HttpPost]
public IActionResult Create()
{
return Ok("Creating an order");
}
}

Generated URLs:

  • GET /api/orders/list → Maps to List.
  • POST /api/orders/create → Maps to Create.

Custom Routes

Custom routes provide flexibility for specific methods:

[Route("api/orders")]
[ApiController]
public class OrdersController : ControllerBase
{
[HttpGet("latest")]
public IActionResult GetLatestOrders()
{
return Ok("Latest orders");
}

[HttpPost("create")]
public IActionResult CreateOrder()
{
return Ok("Order created");
}
}

Generated URLs:

  • GET /api/orders/latest → Maps to GetLatestOrders.
  • POST /api/orders/create → Maps to CreateOrder.

Route Constraints

You can enforce constraints on route parameters for validation:

[HttpGet("{id:int}")]
public IActionResult GetById(int id)
{
return Ok($"Product {id}");
}
  • {id:int} ensures id is an integer. Similarly:
  • {name:minlength(3)} ensures name has at least three characters.

If a request doesn’t meet the constraints, the server returns HTTP 404 Not Found. To customize this behavior, use middleware to handle these cases with tailored responses.

You can create custom constraints implementing IRouteConstraint interface.

Areas

Areas are used to organize controllers into different sections of an application.

Configuration:

[Area("Admin")]
[Route("admin/[controller]/[action]")]
public class DashboardController : Controller
{
public IActionResult Index()
{
return View();
}
}

Resulting URL:
/admin/dashboard/index → Maps to DashboardController.Index.

Conclusion

Understanding and configuring routing in ASP.NET allows you to streamline your application’s behavior and enhance its flexibility. From attribute-based routing to custom constraints, these techniques enable precise control over how endpoints are accessed. In the next post, we’ll delve into securing these routes with authentication and authorization.

Sign up to discover human stories that deepen your understanding of the world.

--

--

Rafael Araujo de Lima
Rafael Araujo de Lima

Written by Rafael Araujo de Lima

A Senior Software Engineer with over 10 years of experience, specializing in software development with a focus on .NET Core, ASP.NET Core, C#.

No responses yet

Write a response