2013-05-21 2 views
28

Я отправляю JSON в контроллер WebAPI, но свойства на модели не связаны.WebAPI POST [FromBody] не является обязательным

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 в качестве параметра и связать его вручную, но похоже, что выше должно быть Just Work (tm)?

Update:

Я изменил способ, чтобы вернуть модель, и я все еще получаю нуль.

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} 

Как вы можете видеть все это оценка хорошо и денди без User префикса запроса JSON полезной нагрузки.

Будьте осторожны с model.Id, потому что id может иметь особое значение, если вы используете его в определении маршрута как часть маршрута. Не путайте 2 вещи (параметры маршрута и те, которые поступают из полезной нагрузки тела запроса).

+0

Я изменил метод, чтобы вернуть модель POSTed, как в вашем примере, но я все еще получаю null. – mattdwen

+2

Следуйте моему примеру шаг за шагом. Создайте новое приложение ASP.NET MVC 4 с помощью базового шаблона. (как показано в моем ответе). Добавьте контроллер API (как показано в моем ответе). Используйте Fiddler и вызовите этот контроллер, используя полезную нагрузку, указанную в моем ответе. Это работает! Я делал это миллионы раз и никогда не имел любые вопросы. –

+2

Это правильный ответ. Проблема заключается в том, что метка {User:} не должна предоставляться в запросе, сам пользовательский объект должен быть корневым. –

24

Вам не хватает заголовка Content-Type в вашем запросе.

К сожалению, даже если вы проверили ModelState, мы не будем передавать информацию об ошибке. Однако хорошей новостью является то, что это поведение было исправлено для нашей следующей версии, и вы увидите ответ на код с кодом 415.

Веб-API требует, чтобы заголовок Content-Type обнаружил правильный форматтер, чтобы десериализовать тело на параметр в действии.

+1

«Content-Type: application/json; charset = utf-8' недействителен? – mattdwen

+1

h mm..из вашего исходного сообщения выше, в нем не было заголовка Content-Type, и у него есть что-то вроде 'Content-Length :: application/json, text/plain, */*' .. была ли это опечатка? .. Кроме того, вы пробовали проверить, есть ли у вас ошибки состояния модели ... вы можете добавить эту проверку и посмотреть 'if (! ModelState.IsValid) { throw new HttpResponseException (Request.CreateErrorResponse (HttpStatusCode.BadRequest, this.ModelState)); } ' –

+0

Хотя немного другая тема, добавление 'contentType': 'application/json; charset = utf-8 'в мой jQuery ajax post помогли. Так что contentType сделал для меня большое значение. Он правильно маршрутизировался в контроллере, но параметр данных всегда был пустым (до сих пор). –

Смежные вопросы