我已经设置了路线模板:
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}/{*wildcard}",
defaults: new { id = RouteParameter.Optional }
);
控制器的动作签名:
public IEnumerable<object> Get(Int64 id,string abc)
我尝试将其与网址http://mymachine.com/api/Individuals/1?abc=4匹配,但它给了我一个例外
{“$ id”:“1”,“消息”:“错误有 发生。“,”ExceptionMessage“:”对象引用未设置为实例 一个 对象 “” ExceptionType。 “:” System.NullReferenceException “ ”堆栈跟踪“:” 在 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} ”会有效。
为什么?
答案 0 :(得分:11)
通配符将告诉路由引擎将URI的其余部分与路由参数匹配(例如,请参阅“按发布日期获取图书”部分in this article)。
它并不意味着将任何任意命名变量与任何参数匹配 - 这是WebApi默认使用查询字符串上的项目而不管您的路由配置(因此您第二个URI工作的原因 - 它与任何路由都不匹配)。
它与您的路线中的{id}
不匹配,因为它期望一个名为{wildcard}
的参数未标记为可选参数。
为了说明,如果你只是将'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});
答案 1 :(得分:4)
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