2013-05-21 125 views
28

我將JSON發佈到WebAPI控制器,但模型上的屬性未被綁定。WebAPI POST [FromBody] not binding

public void Post([FromBody] Models.Users.User model) { 
    throw new Exception(model.Id.ToString()); 
} 

的原始請求如下:

POST http://diva2.local/siteapi/User HTTP/: diva2.local 
Connection: keep-alive 
Content-Length:: application/json, text/plain, */* 
Origin: http://diva2.local 
X-Requested-With: XMLHttpRequest 
User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.: application/json;charset=UTF: http://diva2.local/Users 
Accept-Encoding: gzip,deflate,sdch 
Accept-Language: en-US,en;q=: ISO-8859-1,utf-8;q=0.7,*;q=: .ASPXAUTH=4; __RequestVerificationToken=Rp_hUysjwCjmsxw2 

{"Id":3,"FirstName":"DIVA2","LastName":"User1","Username":"diva1","IsApproved":true,"IsOnlineNow":true,"IsChecked":true} 

每一個例子,我可以找到告訴我,這應該工作,但model.Id == null

但是,如果我改變JSON到:

{User: {"Id":3,"FirstName":"DIVA2","LastName":"User1","Username":"diva1","IsApproved":true,"IsOnlineNow":true,"IsChecked":true}} 

一切正確結合。

這看起來不正確。我想我可以接受JObject作爲參數,並手動綁定它,但感覺上面應該只是工作(tm)?

更新:

我已經改變了返回模型的方法,而我仍然收到空。

public Models.Users.User Post(Models.Users.User user) { 
    return user; 
} 

和響應:

HTTP/1.1 200 OK 
Cache-Control: no-cache 
Pragma: no-cache 
Content-Type: application/json; charset=utf-8 
Expires: -1 
Server: Microsoft-IIS/8.0 
X-AspNet-Version: 4.0.30319 
X-MiniProfiler-Ids: ["a0fab514-d725-4d8f-9021-4931dc06ec4a","fdeeb9a8-9e36-41d8-91d3-5348e880e193","c1b4cc86-d7c3-4497-8699-baac9fa79bf1"] 
X-Powered-By: ASP.NET 
Date: Tue, 21 May 2013 09:06:00 GMT 
Content-Length: 4 

null 
+1

你可以顯示用戶的類定義嗎? –

+3

#facepalm。沒有參數的構造函數。爲有見識的例外歡呼.net! – mattdwen

+1

有沒有這樣的事情,羞辱刪除一個問題? – mattdwen

回答

5

我的用戶模型沒有無參數的構造函數。

+0

這也解決了我的問題。我有一個需要參數的構造函數,並且它對所有參數都接收到null。添加一個空白的無參數構造函數可以解決問題。 –

17

以下工作完全正常對我來說:

型號:

public class User 
{ 
    public int Id { get; set; } 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    public string Username { get; set; } 
    public bool IsApproved { get; set; } 
    public bool IsOnlineNow { get; set; } 
    public bool IsChecked { get; set; } 
} 

控制器:

public class ValuesController : ApiController 
{ 
    public User Post(User user) 
    { 
     return user; 
    } 
} 

請求:

POST http://example.com/api/values HTTP/1.1 
Connection: keep-alive 
Accept: application/json, text/plain, */* 
Content-Type: application/json;charset=UTF-8 
Host: localhost:8816 
Content-Length: 125 

{"Id":3,"FirstName":"DIVA2","LastName":"User1","Username":"diva2user1","IsApproved":true,"IsOnlineNow":true,"IsChecked":true} 

響應:

HTTP/1.1 200 OK 
Cache-Control: no-cache 
Pragma: no-cache 
Content-Type: application/json; charset=utf-8 
Expires: -1 
Server: Microsoft-IIS/8.0 
Date: Tue, 21 May 2013 08:59:02 GMT 
Content-Length: 125 

{"Id":3,"FirstName":"DIVA2","LastName":"User1","Username":"diva2user1","IsApproved":true,"IsOnlineNow":true,"IsChecked":true} 

正如你所看到的一切都是綁定的罰款,沒有在請求JSON有效載荷的User前綴花花公子。

請注意model.Id,因爲如果您在路由定義中將id用作路由的一部分,則它可能具有特殊含義。不要混淆兩件事(路由參數和來自請求主體有效載荷的參數)。

+0

我已經改變了返回POST模型的方法,就像在你的例子中那樣,但是仍然收到null。 – mattdwen

+2

請按照我的示例一步一步創建一個新的使用基本模板的ASP.NET MVC 4應用程序。一個模型(如我的答案中所示)添加一個API控制器(如我的答案中所示)使用Fiddler並使用我的答案中顯示的負載調用此控制器它工作!我已經完成了數百萬次,並且從未任何問題 –

+2

這是正確的答案問題是不應該在請求中提供{User:}標籤,User對象本身應該是根。 –

24

您在請求中缺少Content-Type標題。

不幸的是,即使您檢查過ModelState,我們也不會拋出任何錯誤信息。然而,好消息是,我們即將發佈的版本已經修復了這種行爲,並且您將看到一個基於狀態碼的415響應。

Web API需要Content-Type頭來找出正確的格式化程序,以便將主體反序列化爲操作中的參數。

+1

是'Content-Type:application/json; charset = utf-8'無效? – mattdwen

+1

h mm..from你原來的帖子上面,裏面沒有Content-Type頭文件,它有一些像Content-Length :: application/json,text/plain,*/*'這是一個錯字? 。您是否嘗試過檢查是否有任何模型狀態錯誤...您可以添加此檢查並查看如果(!ModelState.IsValid) {0}新增HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest,this.ModelState )); ' }' –

+0

雖然是一個稍微不同的主題,添加'contentType':'application/json; charset = utf-8'給我的jquery ajax後幫助。所以contentType對我來說有很大的不同。它在控制器中正確路由,但數據參數始終爲空(直到現在)。 –