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:

SourceAttributeZomato URL ExampleUsed For
Route[FromRoute]/api/restaurants/101 β†’ 101 is the IDIDs, required identifiers
Query String[FromQuery]/api/restaurants?city=Blr&rating=4Filters, 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 [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 β†’

Comments on Model Binding (0)

No comments yet. Be the first to share your thoughts!