对于 RESTful 调用,该操作没有任何意义,因为您只想通过 HTTP 方法进行区分。因此,技巧是使用静态操作名称,以便控制器上的不同方法仅在它们接受的 HTTP 方法上有所不同。
虽然MVC框架提供了指定action名称的解决方案 https://stackoverflow.com/questions/6348372,它可以变得更加简洁和不言自明。我们是这样解决的:
特殊属性用于指定 RESTful 方法(这与特殊操作名称匹配):
public sealed class RestfulActionAttribute: ActionNameSelectorAttribute {
internal const string RestfulActionName = "<<REST>>";
public override bool IsValidName(ControllerContext controllerContext, string actionName, MethodInfo methodInfo) {
return actionName == RestfulActionName;
}
}
控制器将其与 HTTP 方法属性结合使用:
public class MyServiceController: Controller {
[HttpPost]
[RestfulAction]
public ActionResult Create(MyEntity entity) {
return Json(...);
}
[HttpDelete]
[RestfulAction]
public ActionResult Delete(Guid id) {
return Json(...);
}
[HttpGet]
[RestfulAction]
public ActionResult List() {
return Json(...);
}
[HttpPut]
[RestfulAction]
public ActionResult Update(MyEntity entity) {
return Json(...);
}
}
为了成功绑定这些控制器,我们使用带有前面提到的属性中的静态操作名称的自定义路由(同时也允许自定义 URL):
routes.MapRoute(controllerName, pathPrefix+controllerName+"/{id}", new {
controller = controllerName,
action = RestfulActionAttribute.RestfulActionName,
id = UrlParameter.Optional
});
请注意,据我所知,这种方法可以轻松满足您的所有要求;您可以在一种方法上拥有多个 [HttpXxx] 属性,以使一种方法接受多个 HTTP 方法。与一些智能的 ModelBinder 配合使用,这是非常强大的。