2012-03-30 45 views
7

让说我有在MVC 4的Web API控制器两种方法:URL参数

public IQueryable<A> Get() {} 

而且

public A Get(int id) {} 

与以下路线:

routes.MapHttpRoute(
    name: "Default", 
    routeTemplate: "{controller}/{id}", 
    defaults: new { id = RouteParameter.Optional } 
); 

这按预期工作。添加一个参数,如:

public IQueryable<A> Get(int p) {} 

public A Get(int id, int p) {} 

导致当MVC以下请求返回404的情况:

GET /controller?p=100 

或者

GET /controller/1?p=100 

与消息“没有行动被发现在与请求匹配的控制器'控制器'上'

我期望URL参数应该通过MVC连接没有问题,但这不是事实。这是一个错误还是我对MVC地图请求行动的误解?

+0

[这里](HTTP不工作://论坛。 asp.net/t/1774984.aspx/2/10)描述了相同的问题,但没有结论是这种行为预期为 – 2012-03-30 13:22:03

+0

PS。由于相同的问题,如果存在多个映射到HTTP动词的方法,则URL中的OData语法将不起作用。 – 2012-03-30 13:26:36

+0

你可以在你的控制器上显示你的实际路线和所有方法和签名吗? – 2012-03-30 13:51:34

回答

8

如果你想到你正在尝试做什么以及你尝试的路线,你会发现你的情况中的第二个参数“p”也需要被标记为一个可选参数。

这是你的路线应该像这样定义:

routes.MapHttpRoute(
name: "Default", 
routeTemplate: "{controller}/{id}/{p}", 
defaults: new { id = RouteParameter.Optional, p = RouteParameter.Optional }); 

一旦你做到这一点,URL

/控制器P = 100 都将映射到

public IQueryable<A> Get(int p) {} 

?方法和URL如下:

/controller/1?p=100 

都将映射到

public A Get(int id, int p) {} 

方法,如您所愿。

所以要回答你的问题....不,这不是一个错误,但作为设计/预期。

+0

这是好的,但据我记得前一段时间使用MVC 2时,常用的方法是只指定方法参数,而不触及路线。例如:[这里](http://stackoverflow.com/questions/627838/asp-net-mvc-getting-querystring-values) - 和MVC应该执行连线的查询部分输入参数的工作。 – 2012-03-30 14:19:06

+0

@pborovik,正如我刚才所说的,“如果你仔细想想”,你会意识到你需要指定第二个参数也是可选的。你不能说第一个参数是可选的,但第二个参数不是可选的。这只是没有意义。 – 2012-03-30 14:26:54

+0

@pborovik如果您为这些方法定义了“重载”,那么在未提供第二个参数的情况下,API控制器将调度到这些方法。但在你的情况下,你只有两种方法,所以调度程序不能调度到任何操作方法。 – 2012-03-30 14:28:52

0

在WebApiConfig添加新的默认为httproute

RouteParameter.Optional为其他路由我

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