我有一个具有以下操作的 Web API Controller :
[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 路由与自定义操作名称结合起来有什么想法吗?
编辑:路由机制不会因 Controller 的选择而混淆。它对单个 Controller 上的action 选择感到困惑。我需要的是在没有指定 Action 时匹配默认 Action 。希望澄清事情。
最佳答案
这是默认操作选择器的预期错误,即ApiControllerActionSelector
。您基本上拥有三个对应于 HTTPPut
动词的操作方法。还要记住,默认操作选择器考虑简单操作参数类型,它们都是原始 .NET 类型,众所周知的简单类型(System.String
、System.DateTime
、System.Decimal
、System.Guid
、System.DateTimeOffset
、System.TimeSpan
”)和底层简单类型(例如:Nullable<System.Int32>
)。
作为您问题的解决方案,我会为以下对象创建两个 Controller :
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)
}
路线如下所示:
routes.MapHttpRoute(
name: "ApiAction",
routeTemplate: "api/Foo/{action}/{id}",
defaults: new { controller = "FooRPC" }
);
routes.MapHttpRoute(
name: "Api",
routeTemplate: "api/Foo/{id}",
defaults: new { id = RouteParameter.Optional, controller = "Foo" }
);
另一方面(与您的主题不完全相关),我有三篇关于 Action 选择的博文,尤其是复杂类型参数。我鼓励您查看它们,因为它们可能会给您更多的视角:
关于c# - 同一个 HttpVerb 的多个操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13115004/