Reputation: 5056
Given following API
public class PagedRequest
{
[Required, Range(1, 100, ErrorMessage = "Limit must be from 1 to 100.")]
public int Top { get; set; }
[Required, Range(0, int.MaxValue, ErrorMessage = "Skip must be 0 or greater.")]
public int Skip { get; set; }
}
[Route("test")]
[HttpGet]
public ActionResult<BarResponse> GetFoos([FromQuery] PagedRequest request)
{
if (!ModelState.IsValid) return BadRequest(ModelState);
// Return 200 OK with data here
}
Works as expected:
Doesn't work as expected
Notes:
Upvotes: 7
Views: 3078
Reputation: 2273
It's likely you're missing the ApiController
attribute on your Controller class. This attribute applies a couple of default conventions which are common for web APIs, but uncommon for web pages. Although honestly I can't really figure out which convention it is that makes your sample work. It probably has something to do with the model binder.
See: https://learn.microsoft.com/en-us/aspnet/core/web-api/?view=aspnetcore-3.0#apicontroller-attribute
Additionally, with the ApiController
attribute you no longer need to check to model state yourself. If the model state is invalid, ASP.NET Core MVC will automatically return a bad request response. So you can remove this part after applying the attribute:
if (!ModelState.IsValid) return BadRequest(ModelState);
Upvotes: 1
Reputation: 93043
You can replace the [Required]
attribute with the [BindRequired]
attribute, which:
Causes model binding to add a model state error if binding cannot occur for a model's property.
public class PagedRequest
{
[BindRequired, Range(1, 100, ErrorMessage = "Limit must be from 1 to 100.")]
public int Top { get; set; }
[BindRequired, Range(0, int.MaxValue, ErrorMessage = "Skip must be 0 or greater.")]
public int Skip { get; set; }
}
Upvotes: 5