Ответ 1
Моя модель пользователя не имела конструктора без параметров.
Я отправляю JSON в контроллер WebAPI, но свойства на модели не связаны.
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:
Я изменил метод, чтобы вернуть модель, и я все еще получаю null.
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
Моя модель пользователя не имела конструктора без параметров.
В запросе отсутствует заголовок Content-Type.
К сожалению, даже если вы проверили ModelState, мы не собираем информацию об ошибке. Тем не менее, хорошая новость заключается в том, что это поведение было исправлено для нашей следующей версии, и вы увидите ответ на код с кодом 415.
Web API требует, чтобы заголовок Content-Type обнаружил правильный форматтер, чтобы десериализовать тело в параметре действия.
Следующее работает отлично для меня:
Модель:
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}
Как вы можете видеть, все связано отлично и dandy без префикса User
в запросе полезной нагрузки JSON.
Будьте осторожны с model.Id
, потому что id
может иметь особое значение, если вы используете его в определениях маршрутов как часть маршрута. Не путайте 2 вещи (параметры маршрута и те, которые поступают из полезной нагрузки тела запроса).
Я обнаружил, что у моего класса есть внутренние сеттеры для всех свойств.
изменения public <property> {get; internal set;}
в public <property> {get; set;}
исправил мою проблему
В моем классе были теги Serializable
и xmlElement
. Несмотря на то, что я указал JSON в качестве типа содержимого в запросах и передал строку JSON, он не будет работать до тех пор, пока они не будут удалены... Похоже, что только атрибут serializable
вызывал проблему.