WebAPI POST [FromBody] not binding

I found that my class had internal setters on all the properties.

Changing public <property> {get; internal set;} to public <property> {get; set;}

fixed my issue


The following works perfectly fine for me:

Model:

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

Controller:

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

Request:

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}

Response:

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}

As you can see everything is bound fine and dandy without the User prefix in the request JSON payload.

Be careful with the model.Id, because id might have a special meaning if you are using it in your route definitions as being part of the route. Do not confuse the 2 things (route parameters and those coming from the request body payload).


My user model did not have a parameter-less constructor.


You are missing the Content-Type header in your Request.

Unfortunately even if you had checked for ModelState, we are not throwing any error information. However, the good news is that this behavior has been fixed for our coming release and you would see a 415 status code based response.

Web API requires the Content-Type header to find out the right formatter to deserialize the body to the parameter on the action.