Reputation: 13955
.Net Core 3.1 API. I've read a lot of threads that ask about why ModelState.IsValid isn't working as expected. Most are for web pages and not API's. And the ones I have found about API's either don't exactly apply or didn't lead me to an understanding.
I have a model that looks like this:
public class MyModel
{
[Required(ErrorMessage = "Prop1 is required.")]
public int Prop1 { get; set; }
public List<int> IntList { get; set; }
}
And I have an API endpoint:
[ApiController]
[Route("api/[controller]")]
public class FooBarController : ControllerBase
{
[HttpPost]
public async Task<IActionResult> Post([FromBody] MyModel request)
{
if (!ModelState.IsValid)
return BadRequest(ModelState);
// do stuff
return Ok(results);
}
}
Now, in Postman, if I pass this as the body, it works as expected:
{ "Prop1": 1001}
But if I pass this, I would expect an error of Prop1 is required.
to be thrown:
{ "Prop2": 1001}
However, there is no error. The model is still valid and I just get back an empty set.
Upvotes: 1
Views: 1421
Reputation: 11889
Integers have a default value of 0, therefore, once initialized, the value of prop1 will be 0, therefore it passes the [Required]
test. If you make prop1 nullable, then required should catch if it is missing.
Or, if you don't want your property to be nullable, you can add a range validator:
[Required(ErrorMessage = "Prop1 is required.")]
[Range(1, int.MaxValue, ErrorMessage = "Prop1 must be greater than 0.")]
public int Prop1 { get; set; }
On a project last year, I created an attribute that was something like [NotNullOrDefault]
which would work with integers being 0, or strings being null, or anything else not having it's default value.
Upvotes: 4