Isaac.

aspnet

Model Binding in ASP.NET Core

Understand how ASP.NET Core binds request data to action parameters.

By Emem IsaacJanuary 16, 20242 min read
#asp.net core#model binding#data binding#routing
Share:

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

  1. Use attributes: Make bindings explicit
  2. Validate early: Check ModelState
  3. Specify sources: Avoid ambiguity
  4. Document parameters: Swagger generation
  5. 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.

Share:

Written by Emem Isaac

Expert Software Engineer with 15+ years of experience building scalable enterprise applications. Specialized in ASP.NET Core, Azure, Docker, and modern web development. Passionate about sharing knowledge and helping developers grow.

Ready to Build Something Amazing?

Let's discuss your project and explore how my expertise can help you achieve your goals. Free consultation available.

💼 Trusted by 50+ companies worldwide | ⚡ Average response time: 24 hours