9

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

    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":"对象引用未设置为对象的实例。","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 }”会起作用。

为什么?

4

2 回答 2

13

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

这并不意味着将任意命名变量与任何参数匹配 - 这是 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});
于 2013-11-01T12:02:55.527 回答
5

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

于 2014-07-31T21:18:15.357 回答