希望對基於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