I have an issue with model binding with ASP.NET Core controllers when trying to bind a list of DTO objects from form data. Using Swagger UI, I try to submit a list of DTO objects, but the list comes through empty.
Here's an example:
[Route("api/test")]
[ApiController]
public class TestController : ControllerBase
{
[HttpPost]
public ActionResult<List<Dto>> Post([FromForm] List<Dto> dtos)
{
// debug here, dtos is empty
return Ok(dtos);
}
}
and here's the DTO:
public class Dto
{
public required string Field { get; set; }
}
I confirmed the issue lies with List<Dto>, because I had no problems with a list of primitives like public ActionResult<List<string>> Post([FromForm] List<string> strings){}.
Also, removing the [FromForm] so that Content-Type: multipart/form-data becomes Content-Type: application/json works, leading me to believe that the issue lies with how ASP.NET handles model binding.
Is there a limitation with binding lists of objects from form data in ASP.NET Core, or am I missing something in my approach/configuration (currently using default webapi scaffold)?
You are correct that the native binding for
[FromForm]cannot handle complex objects within the form data. To accomplish this, you need to help the middleware understand how to bind to theDtoclass. You can do this with a anIModelBinderlike so:and decorate your
Dtoclass with this binder like this:Now you should be able to bind to the models on the form.