WebAPI路由模板中的通配符

我已经设置了一个路由模板:

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

控制器的动作签名:

 public IEnumerable Get(Int64 id,string abc) 

我尝试将其与URL http://mymachine.com/api/Individuals/1?abc=4匹配,但它给了我一个例外

{“$ id”:“1”,“Message”:“发生错误。”,“ExceptionMessage”:“对象引用未设置为对象的实例。”,“ExceptionType”:“System.NullReferenceException”, “StackTrace”:“在System.Web.Http.ValueProviders.Providers.RouteDataValueProvider.d__4.MoveNext()\ r \ n

奇怪的是, http: //mymachine.com/api/Individuals?id = 1& abc = 4确实与控制器,动作和参数相匹配。

我认为“api / {controller} / {id} / {* wildcard}”的“ {id }”将起作用。

为什么?

通配符将告诉路由引擎将URI的其余部分与路由参数匹配(例如,请参阅本文中的“按发布日期获取书籍”部分)。

它并不意味着将任意命名变量与任何参数匹配 – 这是WebApi默认使用查询字符串上的项目而不管您的路由配置(因此您为什么第二个URI工作 – 它与任何路由都不匹配)。

它与您的路线中的{id}不匹配,因为它期望一个名为{wildcard}的参数未被标记为可选。

为了说明,如果您只是将“通配符”更改为“abc”:

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

然后它将成功匹配以下URI:

http://mymachine.com/api/Individual/1/a/b/c

id=1, abc=a/b/c

要修复,只需从路由中删除通配符,使其如下所示:

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

来自gooid的答案是正确的。 我只想回答问题的第二部分:

奇怪的是, http: //mymachine.com/api/Individuals?id = 1& abc = 4确实与控制器,动作和参数相匹配。

由于您有id = RouteParameter.Optional,如果路由不提供id,它仍然匹配路由模板。 占位符{* wildcard}查找路由的其余部分并将其放入“通配符”键下的路由字典中。 在这种情况下,它是空字符串(或null)。

请记住,查询参数也会进入路径词典。 因此,您的路线词典将是:{“id”:“1”,“abc”:“4”,“wildcard”:“”}

欲了解更多信息,请访问http://www.asp.net/web-api/overview/web-api-routing-and-actions/routing-in-aspnet-web-api