Web API反序列化json结果,但所有属性都为null

时间:2014-07-18 17:07:51

标签: c# asp.net-web-api deserialization model-binding

我已经在这个问题上摸不着头几天了。

使用角度$http服务,我将回发到传递Movie json对象的api控制器。在执行正确的操作时,所有模型属性,基元和复杂属性都为null或默认。我使用了JsonProperty属性,因为json对象属性的名称与我需要反序列化的c#模型的名称不同。我还尝试使用DataContract,确保在应用开始时将UseDataContractJsonSerializer设置为true,但这也没有效果。

我还应该注意到我正在使用web api 2.2。

简化型号:

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

动作:

public async Task<HttpResponseMessage> Post(Movie movie) {
    // do stuff
}

来自客户端的调用(在调试中我可以看到电影js对象是用适当的数据补充的):

$http.post('/api/usermovies', { movie : movie });

这是从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"
    }
}

跟踪并没有真正发现任何事情。 modelBinder似乎正在将json与正确的模型正确关联...

  

w3wp.exe信息:0:请求,方法= POST,网址= http://www.moovy.com/api/usermovies,消息='http://www.moovy.com/api/usermovies'

     

w3wp.exe信息:0:Message ='UserMovies',Operation = DefaultHttpControllerSelector.SelectController

     

w3wp.exe信息:0:Message ='Moovy.Api.Controllers.UserMoviesController',Operation = DefaultHttpControllerActivator.Create

     

w3wp.exe信息:0:Message ='Moovy.Api.Controllers.UserMoviesController',Operation = HttpControllerDescriptor.CreateController

     

w3wp.exe信息:0:Message ='Selected action'Post(电影电影)'',Operation = ApiControllerActionSelector.SelectAction

     

w3wp.exe信息:0:Message ='Value read ='Moovy.Models.Movie'',Operation = JsonMediaTypeFormatter.ReadFromStreamAsync

     

w3wp.exe信息:0:Message ='参数'movie'绑定到值'Moovy.Models.Movie'',Operation = FormatterParameterBinding.ExecuteBindingAsync

     

w3wp.exe信息:0:消息='模型状态有效。值:movie = Moovy.Models.Movie',Operation = HttpActionBinding.ExecuteBindingAsync

做什么,该做什么?

2 个答案:

答案 0 :(得分:2)

我明白了。这是因为我在请求中传递电影对象的方式有误。

此...

$http.post('/api/usermovies', { movie : movie });

应改为此......

$http.post('/api/usermovies', movie);

在具有不同属性名称的json对象中反序列化到Movie对象后,在该更改后完美地运行。

答案 1 :(得分:0)

你的类应该是这样的,在VS编辑粘贴特殊,粘贴Json作为类

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