I have set up a route template:
config.Routes.MapHttpRoute(
name: \"DefaultApi\",
routeTemplate: \"api/{controller}/{id}/{*wildcard}\",
The wildcard will tell the routing engine to match the rest of the URI to a route parameter (for an example, see "Get Books By Publication Date" section in this article).
It does not mean match any arbitrary named variable to any parameter - this is something WebApi does by default with items on the querystring regardless of your route configuration (hence why you second URI worked - it didn't match any route).
It did not match {id}
in your route because it was expecting a parameter called {wildcard}
that was not marked as optional.
To illustrate, if you simply changed 'wildcard' to 'abc':
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}/{*abc}",
defaults: new {id = RouteParameter.Optional});
Then it would successfully match the following URI:
http://mymachine.com/api/Individual/1/a/b/c
With the values id=1, abc=a/b/c
To fix, simply remove the wildcard from your route, so that it looks like this:
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new {id = RouteParameter.Optional});
The answer from gooid is correct. I just want to answer the 2nd part of the question:
Strangely, http://mymachine.com/api/Individuals?id=1&abc=4 does match with the controller,action and parameters.
Since you have id = RouteParameter.Optional, if the route doesn't provide id, it still matches the route template. The placeholder {*wildcard} looks for the rest of the route and put it into the Route Dictionary under the key "wildcard". In this case, it is empty string (or null).
Remember that the query parameters also go into the Route Dictionary. Therefore, your Route Dictionary will be: { "id": "1", "abc": "4", "wildcard": ""}
For more info, you can look into http://www.asp.net/web-api/overview/web-api-routing-and-actions/routing-in-aspnet-web-api