2013-05-21 7 views
28

Tôi đang gửi JSON tới bộ điều khiển WebAPI, nhưng các thuộc tính trên mô hình không bị ràng buộc.WebAPI POST [FromBody] không ràng buộc

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

Yêu cầu nguyên liệu như sau:

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} 

Mỗi ví dụ tôi có thể tìm thấy nói với tôi điều này sẽ làm việc, nhưng model.Id == null.

Tuy nhiên, nếu tôi thay đổi JSON để:

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

tất cả mọi thứ liên kết một cách chính xác.

Điều này có vẻ không chính xác. Tôi đoán tôi có thể chấp nhận JObject làm tham số, và ràng buộc nó theo cách thủ công, nhưng nó cảm thấy như trên chỉ cần làm việc (tm)?

Cập nhật:

Tôi đã thay đổi phương pháp để trở lại mô hình, và tôi vẫn nhận được null.

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

Và câu trả lời:

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

Bạn có thể hiển thị định nghĩa lớp cho Người dùng không? –

+3

#facepalm. Không có hàm tạo tham số-ít. Chúc mừng cho ngoại lệ sâu sắc .net! – mattdwen

+1

Có điều gì làm xấu hổ khi xóa câu hỏi không? – mattdwen

Trả lời

5

Mô hình người dùng của tôi không có hàm tạo ít tham số.

+0

Điều này đã giải quyết được vấn đề của tôi. Tôi đã có một hàm tạo yêu cầu các tham số và nó nhận được null cho tất cả các đối số. Việc thêm một hàm tạo trống, tham số-ít cố định vấn đề. –

17

Các công trình sau đây hoàn toàn tốt đẹp cho tôi:

mẫu:

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; } 
} 

Bộ điều khiển:

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

Yêu cầu:

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} 

đáp ứng:

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} 

Như bạn có thể nhìn thấy mọi thứ đều bị ràng buộc tiền phạt và dandy mà không User tiền tố trong yêu cầu JSON tải trọng.

Hãy cẩn thận với model.Id, vì id có thể có ý nghĩa đặc biệt nếu bạn đang sử dụng nó trong định nghĩa tuyến đường của bạn như là một phần của tuyến đường. Đừng nhầm lẫn giữa 2 thứ (thông số tuyến đường và những thứ đến từ tải trọng của thân yêu cầu).

+0

Tôi đã thay đổi phương thức để trả về mô hình POSTED, như trong ví dụ của bạn, nhưng vẫn nhận được null – mattdwen

+2

Thực hiện theo từng bước ví dụ của tôi Tạo một ứng dụng ASP.NET MVC 4 mới bằng cách sử dụng mẫu cơ bản. một mô hình (như được hiển thị trong câu trả lời của tôi) Thêm một bộ điều khiển API (như được hiển thị trong câu trả lời của tôi) Sử dụng Fiddler và gọi bộ điều khiển này bằng cách sử dụng tải trọng được hiển thị trong câu trả lời của tôi. –

+2

Đây là câu trả lời đúng, vấn đề là nhãn {User:} không được cung cấp trong yêu cầu, chính đối tượng người dùng phải là root. –

24

Bạn đang thiếu tiêu đề Loại nội dung trong Yêu cầu của mình.

Thật không may ngay cả khi bạn đã kiểm tra ModelState, chúng tôi không ném bất kỳ thông tin lỗi nào. Tuy nhiên, tin tốt là hành vi này đã được khắc phục cho bản phát hành sắp tới của chúng tôi và bạn sẽ thấy phản hồi dựa trên mã trạng thái 415.

API Web yêu cầu tiêu đề Loại nội dung để tìm ra trình định dạng phù hợp để deserialize phần thân thành tham số trên hành động.

+1

Là 'Content-Type: application/json; charset = utf-8' không hợp lệ? – mattdwen

+1

h mm..từ bài đăng gốc của bạn ở trên, không có tiêu đề Content-Type trong đó và nó có nội dung như 'Content-Length :: application/json, text/plain, */*' ..đây có phải là lỗi đánh máy không? .. Ngoài ra, bạn đã thử kiểm tra xem bạn có bất kỳ lỗi trạng thái mô hình nào không ... bạn có thể thêm kiểm tra này và xem 'if (! ModelState.IsValid) { ném HttpResponseException mới (Request.CreateErrorResponse (HttpStatusCode.BadRequest, this.ModelState)); } ' –

+0

Mặc dù có một chủ đề hơi khác, Thêm 'contentType': 'application/json; charset = utf-8 'đến bài đăng jquery ajax của tôi đã giúp. Vì vậy, contentType tạo ra một sự khác biệt lớn đối với tôi. Nó đã được định tuyến chính xác trong bộ điều khiển, nhưng tham số dữ liệu luôn rỗng (cho đến bây giờ). –