I just started using ASP.NET Web API 2.1 and have encountered a limitation. Using Attribute Routing, I can do the following:
[Route("item/{id:int}")]
public IHttpActionResult GetItem(int id)
{
...
}
The URL /item/5
will be routed to this action, but the URL /item/abc
will not, because of the int
constraint in {id:int}
.
I tried changing my URL so that the id
parameter was in the query string along with its constraint, despite the use of route constraints on query parameters never being mentioned or demonstrated in the documentation.
[Route("item?{id:int}")]
public IHttpActionResult GetItem(int id)
{
...
}
If I try to run now, I get an error on the Configure
method call in Application_Start
.
protected void Application_Start()
{
GlobalConfiguration.Configure(WebApiConfig.Register);
}
The message is as follows.
ArgumentException was unhandled by user code
The route template cannot start with a '/' or '~' character and it cannot contain a '?' character.
Two things bother me about this.
First, the section documenting Route Prefixes on MSDN makes clear that placing a ~
character at the start of the route template is completely acceptable. I tried it, and it works as documented.
Second, if not like this, how can I place a route constraint on a query parameter? Consider the following, with the route constraint removed.
[Route("item")]
public IHttpActionResult GetItem(int id)
{
...
}
The URL /item/5
will be routed to this action, with id
set to 5
- but so will the URL /item/abc
, with id
set to 0
.
Is there no way to place a route constraint on a query parameter?
The key difference between query parameters and route parameters is that route parameters are essential to determining route, whereas query parameters are optional.
You use route constraints to restrict the browser requests that match a particular route. You can use a regular expression to specify a route constraint. For example, imagine that you have defined the route in Listing 1 in your Global. asax file.
Defining multiple constraints We can also apply multiple constraints to the single route to get more control over the URLs with a route. We can apply the multiple constraints to a parameter by a colon (:) separator. [Route(URLPath/{parameterName: constrain:Constrain:….})]
Creating Route Constraint to a Set of Specific Values MapRoute( "Default", // Route name "{controller}/{action}/{id}", // Route Pattern new { controller = "Home", action = "Index", id = UrlParameter. Optional }, // Default values for parameters new { controller = "^H.
According to http://attributerouting.net/#asp-net-web-api(†), this is not possible:
"Beware! Due to integration issues with the Web API WebHost framework, the following features will not work: …
- querystring parameter constraints, …"
†) Note that this answer was written for a previous version of Web API where attribute routing was done using a separate AttributeRouting.WebApi
NuGet package. Attribute routing has since been incorporated into the Web API core. Nevertheless, it appears that constraints on query string parameters are still not supported out of the box.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With