Set your Publisher ID in src/config/ads.ts to display live ads.
Controller-Based Web APIs & Routing
Building RESTful resources with [ApiController], [Route], and ActionResult<T>
Controller-based APIs provide structured, attribute-driven routing for large enterprise architectures where separation of concerns and clear domain boundaries are paramount.
Key Controller Attributes and Response Types
[ApiController]: Enables automatic model validation, attribute routing enforcement, and standard 400 ProblemDetails error responses.
[Route("api/[controller]")]: Sets the route prefix automatically based on class name (e.g., CoursesController becomes /api/courses).
ActionResult<T>: Allows returning both HTTP status codes (NotFound(), BadRequest(), CreatedAtAction()) and strongly-typed objects (Ok(model)).
using Microsoft.AspNetCore.Mvc;
[ApiController]
[Route("api/[controller]")]
public class CoursesController : ControllerBase
{
private static readonly List<CourseDto> _db = new()
{
new CourseDto(1, "Modern ASP.NET Core", 129.99m),
new CourseDto(2, "Advanced C# 12", 99.99m)
};
[HttpGet]
public ActionResult<IEnumerable<CourseDto>> GetAll() => Ok(_db);
[HttpGet("{id:int}")]
public ActionResult<CourseDto> GetById(int id)
{
var course = _db.FirstOrDefault(c => c.Id == id);
if (course == null)
return NotFound(new { Message = $"Course with ID {id} does not exist." });
return Ok(course);
}
[HttpPost]
public ActionResult<CourseDto> Create([FromBody] CourseDto newCourse)
{
_db.Add(newCourse);
return CreatedAtAction(nameof(GetById), new { id = newCourse.Id }, newCourse);
}
}
public record CourseDto(int Id, string Title, decimal Price);Set your Publisher ID in src/config/ads.ts to display live ads.
Test Yourself With Exercise
Which attribute automatically triggers 400 Bad Request responses when model validation rules fail in ASP.NET Core?