我通过以下步骤发现了这个问题:
使用已安装的项目模板创建一个新的 WebApi 项目
转到 Controllers/ValuesController.cs,有两个Get方法,如下所示:
public IEnumerable<string> Get()
// 这个提供GetAll函数public string Get(int id)
// 这个是GetOneById我不喜欢这种设计,因为我认为这两种api方法可以合二为一:
public IEnumerable<string> Get(string ids)
当 ids 为 null 时,返回所有记录,否则按 ids 返回结果(看起来像 id1,id2,id3...)
我也修改了路线:
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{ids}",
defaults: new { ids = RouteParameter.Optional }
);
现在我想一切都准备好了。但是,当我/values
在浏览器中访问时(未指定 ids 参数),我被告知“未找到任何操作”,直到我为以下添加默认值ids
:
public IEnumerable<string> Get(string ids = null)
从现在开始,一切都按我的预期工作。我仍然无法defaults
在路线中移动参数。这意味着:代码将 ids 参数声明为可选两次。
查看位于方法的 MVC4 的源代码System.Web.Http.Controllers.ActionSelectorCacheItem.FindActionUsingRouteAndQueryParameters
,我可以看到在找到正确的操作时忽略了路由中定义的可选参数。我个人认为这真的很糟糕,即使解决方法也很容易。还是我误解了路线和动作方法之间的关系?我认为路由是用于帮助请求找到其相应操作的规则,而“参数是可选的”正是规则的一部分。