Reputation: 6790
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?
Upvotes: 3
Views: 5777
Reputation: 6790
I figured it out. This was because of a mistake in how I was passing the movie object in the request.
This...
$http.post('/api/usermovies', { movie : movie });
Should be changed to this...
$http.post('/api/usermovies', movie);
Deserialization from the json object with differing property names into the Movie
object is working perfectly after that change.
Upvotes: 2
Reputation: 2405
Your class should be like this, in VS edit paste special , Paste Json as classes
public class Rootobject
{
public Movie movie { get; set; }
}
public class Movie
{
public string id { get; set; }
public string title { get; set; }
public int year { get; set; }
public Release_Dates release_dates { get; set; }
public Ratings ratings { get; set; }
public Abridged_Cast[] abridged_cast { get; set; }
public string hashKey { get; set; }
}
public class Release_Dates
{
public string theater { get; set; }
public string dvd { get; set; }
}
public class Ratings
{
public string critics_rating { get; set; }
public int critics_score { get; set; }
public string audience_rating { get; set; }
public int audience_score { get; set; }
}
public class Abridged_Cast
{
public string name { get; set; }
public string id { get; set; }
public string[] characters { get; set; }
}
Upvotes: 0