Wildcard in WebAPI Route template

匿名 (未验证) 提交于 2019-12-03 02:59:02

问题:

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()\r\n

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?

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


回答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



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!