2014-11-22 109 views
8

我有這樣的控制器操作:WebApi POST無[FromBody]工作?

[HttpPost] 
[ActionName("aaa")] 
public HttpResponseMessage aaa(Z z) //notice - no [FromBody] 
{ 
    return Request.CreateResponse(HttpStatusCode.OK, 1); 
} 

其中Z是:

public class Z 
{ 
    public string a { get; set; } 
} 

但是當我通過提琴手發佈:

POST http://localhost:11485/api/profiles/aaa HTTP/1.1 
Content-Type: application/x-www-form-urlencoded; charset=UTF-8 
Host: localhost:11485 
Content-Length: 3 
Accept-Encoding: gzip, deflate 
Accept-Language: en-US,en;q=0.8,he;q=0.6 
Cache-Control: no-cache 
Connection: keep-alive 

a=1 

我可以清楚地看到這是工作:

enter image description here

問:

如果是這樣,它是如何工作的,而不[FromBody]屬性?我還需要/不寫這個屬性?

另外,什麼是不寫這個屬性的場景 - 會導致問題?

+0

有趣的問題。我在這裏找到了一些信息:http://encosia.com/using-jquery-to-post-frombody-parameters-to-web-api/ – 2014-11-22 09:59:32

回答

12

對於MVC和Web API,綁定是不同的。默認情況下,ASP.NET Web API綁定來自請求消息主體的複雜類型以及來自URI,查詢字符串等的簡單類型。由於您指定了Z這是一個類(複雜類型),因此它將從body中填充action方法參數你必須指定[FromBody]。另一方面,如果你的請求是http://localhost:11485/api/profiles/aaa?a=1沒有正文,它不會自動綁定到你的複雜參數。在這種情況下,您需要指定[FromUri],如下所示:public HttpResponseMessage aaa([FromUri]Z z)

另一方面,說你的行動方法是public HttpResponseMessage aaa(string a)。我們現在有string,這是一個簡單的類型。在這種情況下,沒有消息正文的http://localhost:11485/api/profiles/aaa?a=1將使Web API正確綁定參數,而不必指定[FromUri]。現在,如果你想在這種情況下綁定身體,你需要指定public HttpResponseMessage aaa([FromBody]string a)。當然,對於這個機構必須是=1,對於application/x-www-form-urlencoded,沒有密鑰名稱a。底線 - 您的參數(簡單類型或複雜類型)確定Web API綁定的方式。爲了使其工作與默認行爲不同,您需要通過FromUriFromBody來告訴。

PS。無論我上面提到的只是純粹的舊的ASP.NET Web API(包括2)。在ASP.NET 5.0 a.k.a ASP.NET vNext或ASP.NET MVC 6.0中,MVC和Web API已經統一。爲了從身體中綁定複雜類型,您必須指定[FromBody]

+1

非常詳細的解釋。謝謝你,巴德里。作爲一個側面說明,我真的很想知道當MS只發布簡單類型時,他們只允許使用'= 1'模式的想法......我的意思是 - 我不關心它,但生病不得不告訴消費者發送只有= 1。這是非常(!)不好 – 2014-11-22 14:22:35

+0

那麼,身體只讀一次,並綁定到一個參數的整體。例如,您不能將一半身體綁定到一個參數並將其餘部分擱置到另一個參數。當你將body綁定到一個簡單的類型時,根本不需要key,因爲只能綁定參數。但是有點混亂。 – Badri 2014-11-22 15:21:57