How Does Model Binding Work?
Model binding automatically reads incoming request data and converts it into action parameters or .NET model objects.
Request Data Sources
- Route values
- Query string
- Form fields
- Request body
- Uploaded files
Simple Example
Request:
GET /Products/Details/10
Action:
public IActionResult Details(int id)
{
return View();
}
Model binding assigns:
id = 10
Form-to-Model Example
Model:
public class ProductViewModel
{
public string Name { get; set; } = string.Empty;
public decimal Price { get; set; }
}
View:
<form asp-action="Create" method="post">
<input asp-for="Name" />
<input asp-for="Price" />
<button type="submit">Save</button>
</form>
Controller:
[HttpPost]
public IActionResult Create(ProductViewModel model)
{
if (!ModelState.IsValid)
return View(model);
return RedirectToAction("Index");
}
MVC matches the form-field names with the model’s property names:
Name → model.Name
Price → model.Price
Common Binding Attributes
| Attribute | Reads value from |
|---|---|
[FromRoute] |
Route parameter |
[FromQuery] |
Query string |
[FromForm] |
Submitted form |
[FromBody] |
Request body, usually JSON |
[FromHeader] |
HTTP header |
[FromServices] |
Dependency-injection container |
Key Points
- Model binding runs before the action method.
- It converts request strings into .NET data types.
- Matching is generally case-insensitive.
- Binding and conversion errors are stored in
ModelState. - Use
ModelState.IsValidto check binding and validation results. - Use ViewModels instead of binding database entities directly.
- Use
[BindNever]or dedicated ViewModels to prevent overposting.
Model-Binding Sources in ASP.NET Core MVC
Model binding reads incoming request data and assigns it to action parameters or model properties.
| Source | Attribute | Example |
|---|---|---|
| Form fields | [FromForm] |
HTML form submission |
| Request body | [FromBody] |
JSON/XML request |
| Route values | [FromRoute] |
/products/10 |
| Query string | [FromQuery] |
/products?category=laptop |
| HTTP headers | [FromHeader] |
X-Correlation-ID |
| Uploaded files | [FromForm] / IFormFile |
Image or PDF upload |
| Services | [FromServices] |
Dependency-injection service |
Examples
public IActionResult Details([FromRoute] int id)
public IActionResult Search([FromQuery] string keyword)
[HttpPost]
public IActionResult Create([FromForm] ProductViewModel model)
[HttpPost]
public IActionResult Create([FromBody] ProductDto product)
public IActionResult Get(
[FromHeader(Name = "X-Correlation-ID")] string correlationId)
[HttpPost]
public IActionResult Upload([FromForm] IFormFile file)
public IActionResult Index(
[FromServices] IProductService productService)
Default MVC Behaviour
| Parameter type | Common default source |
|---|---|
Simple type such as int or string |
Route, query string or form |
| Complex object in an MVC controller | Form data |
Complex object in an [ApiController] |
Request body |
IFormFile |
Form data |
Key Points
- The binding-source attributes explicitly specify where data must come from.
[FromBody]uses input formatters to deserialize JSON or XML.- Only one parameter should normally read from the request body.
[FromServices]resolves a service; it does not read request data.- Use explicit attributes when the value source may be unclear.