希望对基于REST的API使用GET/PUT/DELETE/POST的相同URL,但是当Actions与它不同的唯一不同是它接受哪个HTTP动词时,它认为它们是重复的!如何基于接受的HTTP动词重载ASP.NET MVC动作?
“类型已经使用相同的参数类型定义了一个名为'Index'的成员。”
我说过,那又怎么样?这个只接受GET,这个只接受POST ......应该可以共存吗?
怎么样?
希望对基于REST的API使用GET/PUT/DELETE/POST的相同URL,但是当Actions与它不同的唯一不同是它接受哪个HTTP动词时,它认为它们是重复的!如何基于接受的HTTP动词重载ASP.NET MVC动作?
“类型已经使用相同的参数类型定义了一个名为'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了解关于如何组织您的路线的一些想法。
“不同的动词也会采用不同的参数”,你能详细说明吗?我认为/ users/[id]是一个很好的URL,可以接受GET,POST,PUT,DELETE都一样...唯一的区别是请求的内容,对吗? – BigOmega 2011-06-14 19:05:51
@Ryan,不,一个会响应POST请求的动作会把你正在创建的视图模型作为动作参数:'[HttpPost] public ActionResult Foo(AModelToCreate model){...}'这当然是不同于只需要'id'的GET操作。 – 2011-06-14 19:08:24
ohhh我需要读进去,我曾经使用的是从Request对象中取出变量... – BigOmega 2011-06-14 19:12:22
虽然ASP.NET MVC将允许您有两个具有相同名称的动作,但.NET不允许您拥有两个具有相同签名的方法 - 即具有相同的名称和参数。
您将需要使用ActionName
属性以不同方式命名方法以告诉ASP.NET MVC它们实际上是相同的操作。
这就是说,如果你在谈论一个GET
和POST
,这个问题可能会消失,因为POST
行动将采取比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));
}
巧妙使用HttpMethod,但违反了SRP。 – Rap 2012-07-16 22:07:14
作为一种解决方法,您可以向其中一个方法添加一个带有默认值的额外参数,只是为了绕过限制并能够构建。
当然要记住,这不是最推荐的做事方式,而且你必须在你的代码中(通过参数名或通过注释)明确这是一个额外的参数,只是为了允许它来构建,当然,确保你已经正确地修饰了你的属性。
一种偏离主题,但我正在用FubuMVC做这件事,值得检查一下,如果你有这样的自由 – heisenberg 2011-06-14 18:47:47