Model Binding in ASP.NET Core
Understand how ASP.NET Core binds request data to action parameters.
A Simple Analogy
Model binding is like an automatic mail sorter. It takes incoming request data and automatically places it into the right parameters.
Why Model Binding?
- Automation: No manual parsing
- Type safety: Automatic conversion
- Validation: Built-in validation
- Convenience: Less code
- Flexibility: Multiple sources
Binding Sources
[ApiController]
[Route("api/[controller]")]
public class OrdersController : ControllerBase
{
[HttpGet("{id}")]
public ActionResult GetOrder(
int id, // From route
[FromQuery] string status, // From query string
[FromHeader] string authorization, // From headers
[FromBody] OrderFilter filter) // From body
{
return Ok();
}
[HttpPost]
public ActionResult Create(
[FromForm] OrderDto orderData, // From form
[FromServices] IOrderService service) // From DI
{
return CreatedAtAction(nameof(GetOrder), new { id = 1 });
}
}
Custom Model Binder
public class DateTimeModelBinder : IModelBinder
{
public Task BindModelAsync(ModelBindingContext bindingContext)
{
var modelName = bindingContext.ModelName;
var valueProviderResult = bindingContext.ValueProvider.GetValue(modelName);
if (valueProviderResult == ValueProviderResult.None)
return Task.CompletedTask;
if (DateTime.TryParse(valueProviderResult.FirstValue, out var date))
{
bindingContext.Result = ModelBindingResult.Success(date);
}
else
{
bindingContext.ModelState.AddModelError(modelName, "Invalid date format");
}
return Task.CompletedTask;
}
}
// Register
builder.Services.AddControllers()
.ConfigureApiBehaviorOptions(options =>
{
options.ModelMetadataDetailsProviders.Add(
new BindingSourceMetadataProvider(
typeof(DateTime),
new DateTimeModelBinder()));
});
Complex Types
public class CreateOrderRequest
{
public string CustomerId { get; set; }
public List<OrderItem> Items { get; set; }
}
public class OrderItem
{
public string ProductId { get; set; }
public int Quantity { get; set; }
}
// Binds automatically
[HttpPost]
public ActionResult Create(CreateOrderRequest request)
{
// request.Items are populated from JSON
return Ok();
}
Validation
public class CreateOrderRequest
{
[Required]
[StringLength(50)]
public string CustomerId { get; set; }
[Required]
[MinLength(1)]
public List<OrderItem> Items { get; set; }
}
[HttpPost]
public ActionResult Create(CreateOrderRequest request)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
// request is valid
return Ok();
}
Best Practices
- Use attributes: Make bindings explicit
- Validate early: Check ModelState
- Specify sources: Avoid ambiguity
- Document parameters: Swagger generation
- Test binding: Verify conversions work
Related Concepts
- Dependency injection
- Routing
- Action filters
- Validation
Summary
Model binding automatically converts request data into action parameters. Use FromRoute, FromQuery, FromBody, and FromForm attributes to control sources.
Related Articles
Attribute Routing in ASP.NET Core
Learn how to use attribute routing for flexible and readable URL patterns in ASP.NET Core applications.
Read More aspnetBackground Services in ASP.NET Core
Implement long-running background services.
Read More aspnetValidation in ASP.NET Core
Learn how to validate user input effectively using ASP.NET Core's built-in and third-party validation tools.
Read More