I've been scratching my head on this one for a few days now.
Using the angular $http service I'm posting back to an api controller passing the Movie json object. And while the correct action is hit, all of the models properties, primitives and complex, are null or default. I've used the JsonProperty attribute because the json objects properties have different names than the c# model that I need to deserialize to. I've also tried using DataContract, being sure to set UseDataContractJsonSerializer to true on app start, but that had no effect also.
I should also note that I'm using web api 2.2.
Simplified Model:
public class Movie {
[DatabaseGenerated(DatabaseGeneratedOption.None)]
[JsonProperty(PropertyName = "id")]
public int Id { get; set; }
[JsonProperty(PropertyName = "title")]
public string Title { get; set; }
[JsonProperty(PropertyName = "year")]
public int Year { get; set; }
[JsonProperty(PropertyName = "release_dates")]
public ReleaseDates ReleaseDates { get; set; }
[JsonProperty(PropertyName = "ratings")]
public Ratings Ratings { get; set; }
[JsonProperty(PropertyName = "abridged_cast")]
public ICollection<Character> Cast { get; set; }
[JsonProperty(PropertyName = "users")]
public ICollection<User> Users { get; set; }
}
Action:
public async Task<HttpResponseMessage> Post(Movie movie) {
// do stuff
}
Call from the client (in debug I can see that the movie js object is hydrated with the proper data):
$http.post('/api/usermovies', { movie : movie });
This is the content in the request being sent from angular:
{
"movie" : {
"id" : "12897",
"title" : "The Matrix",
"year" : 1999,
"release_dates" : {
"theater" : "1999-03-31",
"dvd" : "1999-09-21"
},
"ratings" : {
"critics_rating" : "Certified Fresh",
"critics_score" : 87,
"audience_rating" : "Upright",
"audience_score" : 85
},
"abridged_cast" : [{
"name" : "Keanu Reeves",
"id" : "162654049",
"characters" : ["Neo"]
}, {
"name" : "Laurence Fishburne",
"id" : "162669090",
"characters" : ["Morpheus"]
}, {
"name" : "Carrie-Anne Moss",
"id" : "162669130",
"characters" : ["Trinity"]
}, {
"name" : "Hugo Weaving",
"id" : "162709905",
"characters" : ["Agent Smith"]
}, {
"name" : "Gloria Foster",
"id" : "364627698",
"characters" : ["The Oracle"]
}
],
"$$hashKey" : "00C"
}
}
Tracing doesn't really turn up anything. The modelBinder seems to be properly associating the json with the correct model...
w3wp.exe Information: 0 : Request, Method=POST, Url=http://www.moovy.com/api/usermovies, Message='http://www.moovy.com/api/usermovies'
w3wp.exe Information: 0 : Message='UserMovies', Operation=DefaultHttpControllerSelector.SelectController
w3wp.exe Information: 0 : Message='Moovy.Api.Controllers.UserMoviesController', Operation=DefaultHttpControllerActivator.Create
w3wp.exe Information: 0 : Message='Moovy.Api.Controllers.UserMoviesController', Operation=HttpControllerDescriptor.CreateController
w3wp.exe Information: 0 : Message='Selected action 'Post(Movie movie)'', Operation=ApiControllerActionSelector.SelectAction
w3wp.exe Information: 0 : Message='Value read='Moovy.Models.Movie'', Operation=JsonMediaTypeFormatter.ReadFromStreamAsync
w3wp.exe Information: 0 : Message='Parameter 'movie' bound to the value 'Moovy.Models.Movie'', Operation=FormatterParameterBinding.ExecuteBindingAsync
w3wp.exe Information: 0 : Message='Model state is valid. Values: movie=Moovy.Models.Movie', Operation=HttpActionBinding.ExecuteBindingAsync
What to do, what to do?