Model Binding & Validation
How your API gets data from the URL + why 400 Bad Request happens.
The Rule: 90% of 400 errors = You sent data to wrong place, or in wrong format.
1. The 3 Places Data Comes From - Zomato Example
When you order pizza, data comes from 3 places:
| Source | Attribute | Zomato URL Example | Used For |
|---|---|---|---|
| Route | [FromRoute] | /api/restaurants/101 β 101 is the ID | IDs, required identifiers |
| Query String | [FromQuery] | /api/restaurants?city=Blr&rating=4 | Filters, sorting, pagination |
| Request Body | [FromBody] | JSON: { "name":"Pizza", "qty":2 } | POST/PUT data, complex objects |
2. Code It: Zomato Search API
Goal: GET /api/zomato/restaurants/101?includeMenu=true
[HttpGet("restaurants/{id}")]
public ActionResult GetRestaurant(
[FromRoute] int id, // From URL path: 101
[FromQuery] bool includeMenu // From?includeMenu=true
) {
var r = FindRestaurant(id);
if(r == null) return NotFound();
if(includeMenu) r.Menu = GetMenu(id);
return Ok(r);
}
3. Validation: Stop Bad Data at the Door
Theory: [ApiController] gives you auto 400 validation. Never trust client data.
Add to your Order.cs model:
public class Order {
[Required(ErrorMessage = "Restaurant ID is required")]
public int RestaurantId { get; set; }
[Range(1, 10, ErrorMessage = "Quantity must be 1-10")]
public int Quantity { get; set; }
[StringLength(200)]
public string Notes { get; set; }
}
Now POST this: { "Quantity": 0 }
API returns 400 instantly: {"errors": {"Quantity": ["Quantity must be 1-10"]}}
Your code never ran. Crash prevented.
Career-Killer Mistake: Forgetting
Why: Without
[FromBody] on POST. public IActionResult Create(Order order) β 415 Unsupported Media Type. Why: Without
[FromBody], API expects data in URL. But you sent JSON. Framework canβt find it. Complex types need [FromBody].
Quick Check π§
You can now prevent 400 errors. Next: Routing & URL Design - How to structure URLs like
/api/v1/users/5/orders. Good URLs = good APIs. Continue β
No comments yet. Be the first to share your thoughts!