Reputation: 4239
I have a .Net Core 2.2 Web API. One of my controller action methods takes two query string parameter, a year and a month.
GET: /api/ItemsForMonth?year=2019&month=8
The action method looks like this:
[HttpGet]
public async Task<ActionResult<IEnumerable<Item>>> GetItemsForMonth([FromQuery] int year, [FromQuery] int month)
{
if (year <= 2000 || month <= 0 || month > 13)
return BadRequest("Please check the year and month parameters.");
}
So I am checking to make sure that the year is greater than 2000, and the month is between 1 and 12.
Is that the best way of doing it? I know if the parameters were part of the route instead of query strings (and maybe they should be?) I could do this
GET: /api/ItemsForMonth/2019/8
[HttpGet("/{year:int:min(2000)}/{month:int:min(1):max(12)}")]
public async Task<ActionResult<IEnumerable<Item>>> GetItemsForMonth()
{
}
But is there something similar for query string parameters?
Thanks
Upvotes: 6
Views: 12659
Reputation: 4934
yes, now there is. Refer to the following docs page: https://learn.microsoft.com/en-us/aspnet/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2#route-constraints
here's the sample code:
[HttpGet("/{year:int:min(2000)}/{month:int:min(1):max(12)}/{query:maxlength(15)}")]
public async Task<ActionResult<IEnumerable<Item>>> GetItemsForMonth()
{
}
notice the "/{query:maxlength(15)}" in the end of the route params list.
Upvotes: 1
Reputation: 28434
One approach would be to bind the query parameters into a model and use basic attribute-based model validation:
class DateQueryParameters {
[Required]
[Range(2000, int.MaxValue)]
public int Year {get;set;}
[Required]
[Range(1, 12)]
public int Month {get;set;}
}
[HttpGet]
public async Task<IActionResult> GetItemsForMonth([FromQuery] DateQueryParameters dateParameters)
{
if(!this.ModelState.IsValid){
return Task.FromResult(this.BadRequest(this.ModelState));
}
}
Model validation will be done automatically if your controller is decorated with the ApiController
attribute.
Upvotes: 15