Web API路由模板中的通配符

时间:2013-11-01 11:11:31

标签: c# asp.net asp.net-mvc asp.net-web-api

我已经设置了路线模板:

    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} ”会有效。

为什么?

2 个答案:

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