2011-06-14 133 views
23

希望對基於REST的API使用GET/PUT/DELETE/POST的相同URL,但是當Actions與它不同的唯一不同是它接受哪個HTTP動詞時,它認爲它們是重複的!如何基於接受的HTTP動詞重載ASP.NET MVC動作?

「類型已經使用相同的參數類型定義了一個名爲'Index'的成員。」

我說過,那又怎麼樣?這個只接受GET,這個只接受POST ......應該可以共存嗎?

怎麼樣?

+1

一種偏離主題,但我正在用FubuMVC做這件事,值得檢查一下,如果你有這樣的自由 – heisenberg 2011-06-14 18:47:47

回答

35

這不是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瞭解關於如何組織您的路線的一些想法。

+0

「不同的動詞也會採用不同的參數」,你能詳細說明嗎?我認爲/ users/[id]是一個很好的URL,可以接受GET,POST,PUT,DELETE都一樣...唯一的區別是請求的內容,對嗎? – BigOmega 2011-06-14 19:05:51

+0

@Ryan,不,一個會響應POST請求的動作會把你正在創建的視圖模型作爲動作參數:'[HttpPost] public ActionResult Foo(AModelToCreate model){...}'這當然是不同於只需要'id'的GET操作。 – 2011-06-14 19:08:24

+0

ohhh我需要讀進去,我曾經使用的是從Request對象中取出變量... – BigOmega 2011-06-14 19:12:22

8

雖然ASP.NET MVC將允許您有兩個具有相同名稱的動作,但.NET不允許您擁有兩個具有相同簽名的方法 - 即具有相同的名稱和參數。

您將需要使用ActionName屬性以不同方式命名方法以告訴ASP.NET MVC它們實際上是相同的操作。

這就是說,如果你在談論一個GETPOST,這個問題可能會消失,因爲POST行動將採取比GET更多的參數,因此可以區分的。

所以,你需要兩種:

[HttpGet] 
public ActionResult ActionName() {...} 

[HttpPost, ActionName("ActionName")] 
public ActionResult ActionNamePost() {...} 

或者:

[HttpGet] 
public ActionResult ActionName() {...} 

[HttpPost] 
public ActionResult ActionName(string aParameter) {...} 
1

另一種選擇是有一個接受所有和之間的區別列舉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)); 
      } 
+2

巧妙使用HttpMethod,但違反了SRP。 – Rap 2012-07-16 22:07:14

0

作爲一種解決方法,您可以向其中一個方法添加一個帶有默認值的額外參數,只是爲了繞過限制並能夠構建。

當然要記住,這不是最推薦的做事方式,而且你必須在你的代碼中(通過參數名或通過註釋)明確這是一個額外的參數,只是爲了允許它來構建,當然,確保你已經正確地修飾了你的屬性。