2013-11-01 64 views
6

我已经设置了路由模板:通配符的WebAPI路径模板

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

控制器的动作签名:

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

我试图用URL http://mymachine.com/api/Individuals/1?abc=4匹配它,但它给了我一个异常

{“$ id”:“1”,“Message”:“发生了错误 ”,“ExceptionMessage”:“对象引用不是s “,”ExceptionType“:”System.NullReferenceException“,”StackTrace“:” at System.Web.Http.ValueProviders.Providers.RouteDataValueProviderrs.Providers.RouteDataValueProvider.d__4.MoveNext()\ r \ n

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

我想起了 “(编号)” “API/{}控制器/ (编号)/{*}通配符” 将起作用。

为什么?

+0

你不能有可选参数,然后是非可选的参数!另外,如果您将abc作为查询字符串传递,那么您不需要在路由中使用它!如果我在你的位置,我会重做我的路线......给它一个想法 –

回答

7

通配符将告诉路由引擎将URI的其余部分与路由参数相匹配(例如,请参阅“按出版日期获取书籍”部分in this article)。

这并不意味着任何参数都可以匹配任何命名变量 - 这是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}); 
4

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

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

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

请记住,查询参数也进入路由字典。因此,你的路线字典将是: { “ID”: “1”, “ABC”: “4”, “通配符”: “”}

欲了解更多信息,你可以看看http://www.asp.net/web-api/overview/web-api-routing-and-actions/routing-in-aspnet-web-api