我有一个Web API控制器,其操作如下:
[HttpPut]
public string Put(int id, JObject data)
[HttpPut, ActionName("Lock")]
public bool Lock(int id)
[HttpPut, ActionName("Unlock")]
public bool Unlock(int id)
以下路线已映射:
routes.MapHttpRoute(
name: "Api",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
routes.MapHttpRoute(
name: "ApiAction",
routeTemplate: "api/{controller}/{action}/{id}"
);
当我提出以下请求时,一切都按预期工作:
PUT /api/items/Lock/5
PUT /api/items/Unlock/5
但是当我试图提出要求时:
PUT /api/items/5
我得到以下异常:
Multiple actions were found that match the request:
Put(int id, JObject data)
Lock(int id)
Unlock(int id)
我尝试在默认路由中添加一个空操作名称,但这没有帮助:
[HttpPut, ActionName("")]
public string Put(int id, JObject data)
如何将默认RESTful路由与自定义操作名称相结合?
编辑:路由机制不会因控制器的选择而混淆。在单个控制器上选择 动作 会让人感到困惑。我需要的是在没有指定动作时匹配默认动作。希望澄清一切。
答案 0 :(得分:6)
这是默认操作选择器ApiControllerActionSelector
的预期错误。您基本上有三个对应于HTTP Put
动词的动作方法。还要记住,默认操作选择器会考虑简单的操作参数类型,它们都是原始的.NET类型,众所周知的简单类型(System.String
,System.DateTime
,System.Decimal
,{{1} },System.Guid
,System.DateTimeOffset
)和基础简单类型(例如:System.TimeSpan
)。
作为您问题的解决方案,我将为以下内容创建两个控制器:
Nullable<System.Int32>
路线如下所示:
public class FooController : ApiController {
public string Put(int id, JObject data)
}
public class FooRPCController : ApiController {
[HttpPut]
public bool Lock(int id)
[HttpPut]
public bool Unlock(int id)
}
另一方面(与您的主题不完全相关),我有三篇关于动作选择的博客文章,特别是复杂的类型参数。我鼓励你检查一下,因为他们可能会给你更多的观点:
答案 1 :(得分:2)
在Giscard Biamby的帮助下,我发现this answer指出了我正确的方向。最后,为了解决这个具体问题,我这样做了:
routes.MapHttpRoute(
name: "ApiPut",
routeTemplate: "api/{controller}/{id}",
defaults: new { action = "Put" },
constraints: new { httpMethod = new HttpMethodConstraint("Put") }
);
谢谢@GiscardBiamby
答案 2 :(得分:-3)
首先,删除[HttpPut, ActionName("")]
,然后修改您的路线
config.Routes.MapHttpRoute(
name: "Api",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional },
constraints: new { id = @"^[0-9]+$" }
);