Для вызовов RESTful действие не имеет смысла, так как вы хотите отличаться только HTTP-методами. Таким образом, хитрость заключается в том, чтобы использовать статическое имя действия, чтобы разные методы контроллера отличались только в методе HTTP, который они принимают.
Хотя инфраструктура MVC предоставляет решение для указания имен действий , ее можно сделать более лаконичной и понятной. Мы решили это так:
Специальный атрибут используется для указания методов 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. В сочетании с некоторыми умными (er) ModelBinder это очень мощный.