Reputation: 2149
I am newbie to ASP.NET core platform. I am working on sample application where I am pooling some daily data from service. My API signature as below -
[HttpGet("daily/{state}/{year}/{month}/{day}")]
public async Task<IActionResult> Daily([FromRoute] string state, [FromRoute] int year, [FromRoute] int month, [FromRoute] int day)
{
//...
}
My requirement is to restrict state
parameter to 3 characters and all caps.
So I did this -
[HttpGet("daily/{state:regex(A-Z):maxlength(3)}/{year}/{month}/{day}")]
public async Task<IActionResult> Daily([FromRoute] string state, [FromRoute] int year, [FromRoute] int month, [FromRoute] int day)
{
//...
}
If I add these constraints on route, I am getting page not found error.
It works fine if I put no constraint.
Updated - See following screen-shot from VS2017. I am passing URL like http://localhost:51208/api/daily/mah/2018/08/13
and still ModelState's IsValid returns true. Why?
Upvotes: 1
Views: 2266
Reputation: 247133
Not found is because the URL being called most likely does not match the regex constraint.
Consider checking your regular expression.
Simple example
^[A-Z]{1,3}$
Matches a single character in the range: [A-Z] between 1 and 3 times.
That means it will match from A
to ZZZ
If the length must be exactly 3 characters then remove the range
^[A-Z]{3}$
Which will match AAA
to ZZZ
So update the constraint accordingly.
[HttpGet("daily/{state:regex(^[[A-Z]]{{3}}$)}/{year:int}/{month:int}/{day:int}")]
Note that Regular expression tokens must be escaped. For example,
\
,{
,}
,[
,]
characters need to be escaped by doubling them to escape the Routing parameter delimiter characters.
Reference Routing in ASP.NET Core: Regular expressions about escaping the regular expression.
For the desired match
GET {host}/daily/ABC/2019/01/20
Upvotes: 2
Reputation: 2022
What you can do is in a more cleaner way is make a model for your get request.
public class DailyModel
{
[Required]
[RegularExpression("^[A-Z]{3}$", ErrorMessage ="State should be length of 3 and all in Upper Case")]
public string State { get; set; }
public int Year { get; set; }
public int Month { get; set; }
public int Day { get; set; }
}
And apply data annotation to your fields like the above code. And on your controller, you can send the model state invalid message if the request is not valid.
[Route("api/[controller]")]
public class TestController : Controller
{
[HttpGet("daily/{state}/{year}/{month}/{day}")]
public async Task<IActionResult> Daily([FromRoute] DailyModel model)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
...
}
}
Upvotes: 3