Wildcard in WebAPI Route template

I have set up a route template:

    config.Routes.MapHttpRoute(
        name: "DefaultApi",
        routeTemplate: "api/{controller}/{id}/{*wildcard}",
        defaults: new { id = RouteParameter.Optional }
        );

controller’s action signature:

public IEnumerable<object> Get(Int64 id,string abc)

I tried to match it with URL http://mymachine.com/api/Individuals/1?abc=4, but it gives me an exception

{“$id”:”1″,”Message”:”An error has
occurred.”,”ExceptionMessage”:”Object reference not set to an instance
of an
object.”,”ExceptionType”:”System.NullReferenceException”,”StackTrace”:”
at
System.Web.Http.ValueProviders.Providers.RouteDataValueProvider.d__4.MoveNext()rn

Strangely, http://mymachine.com/api/Individuals?id=1&abc=4 does match with the controller,action and parameters.

I thought “{id}” of “api/{controller}/{id}/{*wildcard}” will work.

Why?

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

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});

Method 2

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


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x