I have an ASP.NET Web API application where I want to respond to the following routes:
1. http://localhost:1234/values
2. http://localhost:1234/values/123
3. http://localhost:1234/values/large
4. http://localhost:1234/values/small
Note: These routes and examples are just that, examples. But they map to what I want achieve.
- Should return all values, say a list of numbers.
- Should return the value of the resouce with id 123.
- Should return a list of what the app considers large values. Whatever that may be.
- Should return a list of what the app consider small values.
As with a billion ASP.NET Web Api routing examples, number (1) and (2) are straightforward. But when I try and resolve (3) and (4), then (1) and (2) are no longer working.
This is the routes I have at the moment:
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
// trying to map to "values/large" or "values/small"
routes.MapHttpRoute(
name: "ActionsApi",
routeTemplate: "{controller}/{action}",
defaults: null,
constraints: new { action = @"^[a-zA-Z]+$" }
);
// trying to map to "values/123"
routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "{controller}/{id}",
defaults: null,
constraints: new { id = @"^\d+$" }
);
// trying to map to "values"
routes.MapHttpRoute(
name: "ControllerApi",
routeTemplate: "{controller}"
);
With the above routes, (3) and (4) work.
(2) returns:
<string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">
No action was found on the controller 'Values' that matches the name '123'.
</string>
And (1) returns:
<string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">
Multiple actions were found that match the request:
System.Collections.Generic.IEnumerable`1[System.String] Get() on type MvcApplication3.Controllers.ValuesController
System.Collections.Generic.IEnumerable`1[System.String] Large() on type MvcApplication3.Controllers.ValuesController
System.Collections.Generic.IEnumerable`1[System.String] Small() on type MvcApplication3.Controllers.ValuesController
</string>
I am at a loss as to how to setup the routes to support the 4 API examples I listed above.
EDIT: Thanks to David, he pointed out that \w also matched digits, hence a problem. I changed it to [a-zA-Z]+ to match large and small.
Now all work except for (1).
EDIT 2 As suggested by @andrei I made the id parameter optional, to try and get (1) working, but resulted in the following error for that route:
The resource cannot be found.
Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly.
The optional default I added here:
routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "{controller}/{id}",
defaults: new { id = RouteParameter.Optional },
constraints: new { id = @"^\d+$" }
);
123looks like it is a match for regex^\w+$.