想要对基于 REST 的 API 的 GET/PUT/DELETE/POST 使用相同的 URL,但是当 Actions 的唯一不同之处在于它接受哪些 HTTP 动词时,它认为它们是重复的!
“类型已经定义了一个名为 'Index' 的成员,具有相同的参数类型。”
我说的,那又怎样?这个只接受GET,这个只接受POST……应该可以共存吧?
如何?
想要对基于 REST 的 API 的 GET/PUT/DELETE/POST 使用相同的 URL,但是当 Actions 的唯一不同之处在于它接受哪些 HTTP 动词时,它认为它们是重复的!
“类型已经定义了一个名为 'Index' 的成员,具有相同的参数类型。”
我说的,那又怎样?这个只接受GET,这个只接受POST……应该可以共存吧?
如何?
这不是 ASP.NET MVC 限制或其他什么。它是 .NET 以及类的工作方式:无论您多么努力,都不能在同一个类上拥有两个具有相同名称的方法,它们采用相同的参数。[ActionName]
您可以使用以下属性作弊:
[HttpGet]
[ActionName("Foo")]
public ActionResult GetMe()
{
...
}
[HttpPut]
[ActionName("Foo")]
public ActionResult PutMe()
{
...
}
[HttpDelete]
[ActionName("Foo")]
public ActionResult DeleteMe()
{
...
}
[HttpPost]
[ActionName("Foo")]
public ActionResult PostMe()
{
...
}
当然,在真正的 RESTFul 应用程序中,不同的动词也会采用不同的参数,因此您很少会遇到这种情况。
您可以查看SimplyRestful,了解有关如何组织您的路线的一些想法。
虽然 ASP.NET MVC 将允许您拥有两个具有相同名称的操作,但 .NET 不允许您拥有两个具有相同签名的方法 - 即相同的名称和参数。
您需要以不同的方式命名方法,使用该ActionName
属性告诉 ASP.NET MVC 它们实际上是相同的操作。
也就是说,如果您在谈论 aGET
和 a POST
,这个问题可能会消失,因为该POST
操作将采用比 the 更多的参数GET
,因此是可区分的。
因此,您需要:
[HttpGet]
public ActionResult ActionName() {...}
[HttpPost, ActionName("ActionName")]
public ActionResult ActionNamePost() {...}
或者:
[HttpGet]
public ActionResult ActionName() {...}
[HttpPost]
public ActionResult ActionName(string aParameter) {...}
另一种选择是拥有一个接受所有并区分 HttpMethod 并从那里调用适当代码的单一方法。例如
string httpMethod = Request.HttpMethod.ToUpperInvariant();
switch (httpMethod)
{
case "GET":
return GetResponse();
case "POST":
return PostResponse();
default:
throw new ApplicationException(string.Format("Unsupported HttpMethod {0}.", httpMethod));
}
作为一种解决方法,您可以向其中一个方法添加一个具有默认值的额外参数,以绕过限制并能够构建。
当然请记住,这不是最推荐的做事方式,而且您必须在代码中(通过参数名称或通过注释)明确这是一个额外的参数,只是为了允许它构建,当然要确保你正确地装饰了你的属性。