Controllers and Routing
Level: Intermediate
ℹ️ What You'll Learn
- Controller purpose: Organize related endpoints (StudentsController for student endpoints, TeachersController for teacher endpoints)
[ApiController]attribute: Auto-validates input, returns 400 Bad Request if validation fails, returns problem details on errorControllerBase: Base class for API controllers (JSON responses, no View support)[Route("api/[controller]")]: Base route for all actions in controller (StudentsController → api/students)[HttpGet]: Handle GET requests (read data, safe, idempotent)[HttpPost]: Handle POST requests (create new resource)- HttpPut: Handle PUT requests (update entire resource by ID)
- HttpDelete: Handle DELETE requests (delete resource by ID)
- Route parameters: HttpGet captures id from URL path for resource identification
- Route constraints: Constrain parameters to specific types (int, guid) for validation
[FromRoute]: Explicit binding from URL parameter (usually not needed, inferred from parameter name)[FromQuery]: Binding from query string (?className=10A→ className parameter)[FromBody]: Binding from request body (POST/PUT with JSON → Student object)- API versioning:
[Route("api/v1/[controller]")]for version 1,api/v2/[controller]for version 2 - School Management controller structure: StudentsController, TeachersController, ExamsController, FeesController, AttendanceController
- Action naming: GetStudents (GET all), GetStudent (GET by ID), CreateStudent (POST), UpdateStudent (PUT), DeleteStudent (DELETE)
Controller Basics
File: Controllers/StudentsController.cs
[ApiController]
[Route("api/[controller]")]
public class StudentsController : ControllerBase
{
// Actions here
}
[ApiController] = automatic model validation, problem details response.
[Route("api/[controller]")] = base route /api/students
Route Definition
[HttpGet] // GET /api/students
public async Task<ActionResult<List<Student>>> GetStudents()
[HttpGet("{id}")] // GET /api/students/101
public async Task<ActionResult<Student>> GetStudent(int id)
[HttpPost] // POST /api/students
public async Task<ActionResult<Student>> CreateStudent([FromBody] Student student)
[HttpPut("{id}")] // PUT /api/students/101
public async Task<ActionResult> UpdateStudent(int id, [FromBody] Student student)
[HttpDelete("{id}")] // DELETE /api/students/101
public async Task<ActionResult> DeleteStudent(int id)
Route Constraints
[HttpGet("{id:int}")] // id must be integer
[HttpGet("{id:guid}")] // id must be GUID
[HttpGet("{id:min(1)}")] // id >= 1
[HttpGet("search/{query}")] // exact match
Multiple Controllers
SMS API structure:
// StudentsController
[Route("api/[controller]")]
public class StudentsController : ControllerBase
// ExamsController
[Route("api/[controller]")]
public class ExamsController : ControllerBase
// FeesController
[Route("api/[controller]")]
public class FeesController : ControllerBase
Routes:
/api/students/api/exams/api/fees
Custom Routes
[Route("api/student")]
public class StudentController : ControllerBase
{
[HttpGet("active")]
public async Task<ActionResult<List<Student>>> GetActiveStudents()
{
// GET /api/student/active
}
[HttpGet("class/{className}")]
public async Task<ActionResult<List<Student>>> GetByClass(string className)
{
// GET /api/student/class/10-A
}
}
Route Order
Routes evaluated top-to-bottom:
[HttpGet("{id:int}")] // Specific routes first
public async Task<ActionResult<Student>> GetStudent(int id)
[HttpGet("{name}")] // General routes last
public async Task<ActionResult<Student>> GetStudentByName(string name)
Key Takeaways
- Controller = organize related endpoints
- Route = URL path
- Constraints = validate route parameters
- Attribute routing = flexible, explicit
💡 Routing Tip
Keep routes simple and RESTful. /api/students/{id} not /api/get-student-by-id.
🤖Use AI to Learn Faster
Use ChatGPT, Claude, or Copilot to go deeper on Controllers and Routing. Try these prompts:
"What's the purpose of [ApiController]?""How do I use route constraints?""When should I create new controllers?""Quiz me on routing"
💡 Tip: After reading this article, paste your own code into AI and ask "What could go wrong here and why?" — fastest way to find edge cases and deepen understanding.
nexcoding.in
Have questions on your tech stack, ongoing projects, or need one-to-one training?