aspnetcore
aspnetcore copied to clipboard
ASP.NET core inconsistent model binding from form-data and json when trying to bind to an IEnumerable<T>
Is there an existing issue for this?
- [X] I have searched the existing issues
Describe the bug
Model binding from form-data seems to work differently than model binding from json.
Expected Behavior
No response
Steps To Reproduce
Create a simple Web API with controllers. Also have Nullable enabled in the csproj. Create the following controller and model:
[ApiController]
[Route("[controller]")]
public class ApiController : ControllerBase
{
[HttpPost("[action]")]
public IActionResult PostFormData([FromForm] PostRequest request) =>
Ok(string.Join(",", request.Values ?? ["<none>"]));
[HttpPost("[action]")]
public IActionResult PostJson(PostRequest request) =>
Ok(string.Join(",", request.Values ?? ["<none>"]));
}
public record PostRequest
{
public IEnumerable<string> Values { get; set; } = [];
}
Note that the Values property has a default value in the PostRequest record.
When calling the PostJson method on the controller, the model is bound as expected (screenshot from Postman):
When calling the PostFormData method, though, the application returns an error:
The error is:
{
"type": "https://tools.ietf.org/html/rfc9110#section-15.5.1",
"title": "One or more validation errors occurred.",
"status": 400,
"errors": {},
"traceId": "00-3ea96923dfbfea72ba0c067b226b3985-0d099b1cc0b1cb3d-00"
}
I might be missing something, but there seems to be other strange behavior on the PostFormData method, i.e. when the model is bound from form-data:
- Removing the default value of
[](i.e. leaving it null), will not raise an error and the model property is bound as expected. - When the default value is a collection with number of elements that is equal or greater than the elements passed in the form-data (e.g. default value of
["x", "x", "x"]), then an error is not raised but the bound collection retains the default value (["x", "x", "x"]) and not the one passed in the form-data. - Changing the
Valuesproperty type to one ofstring[],List<string>,ICollection<string>seems to prevent the app from raising the error.
Exceptions (if any)
No response
.NET Version
8.0.200
Anything else?
No response