正在反序列化复杂的Json对象



我想反序列化一个复杂的,比如说构造不好的json。我编写的代码没有反序列化对象,MovieInfo属性为null。您可以在代码中找到示例json。我希望避免使用JObject.Parsedynamic对象。我在这里错过了什么?

using System.Collections.Generic;
using Newtonsoft.Json;
namespace ComplexJsonExample
{
    class Program
    {
        static void Main(string[] args)
        {
            string jsonInText = @"
            {
                ""movies"" : [
                    { 
                        ""Harry Potter"" : [
                            { ""rating"": ""great""}, 
                            { ""rating"": ""horrible""}
                        ]
                    },
                    { 
                        ""Guardians of the galaxy"" : [
                            { ""rating"": ""cool""}, 
                            { ""rating"": ""awesome""}
                        ]
                    }
                ]
            }
            ";
            var movieList = JsonConvert.DeserializeObject<MovieList>(jsonInText);
        }
    }
    public class MovieList
    {
        [JsonProperty("movies")]
        public IList<Movie> Movies { get; set; }
    }
    public class Movie
    {
        IDictionary<string, IList<MovieRating>> MovieInfo { get; set; }
    }
    public class MovieRating
    {
        [JsonProperty("rating")]
        public string Rating { get; set; }
    }
}

这有点难看,但你可以这样做:

class MovieList
{
    [JsonProperty("movies")]
    public Movie[] Movies { get; set; }
}
class Movie : Dictionary<string, MovieRating[]>
{
}
class MovieRating
{
    [JsonProperty("rating")]
    public string Rating { get; set; }
}

奇怪的是,这部电影是一个只有一个键(标题)的字典,但它与JSON结构相匹配。在反序列化之后,您总是可以将它映射到更明智的东西。

我认为这有点像黑客,但它有效,并将json字符串反序列化为所需的格式:

class MovieConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(Movie);
    }
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {            
        var movie = new Movie(){
            MovieInfo = new Dictionary<string,IList<MovieRating>>()
        };
        while (reader.Read() && reader.Value != null)
        {                
            var name = (string)reader.Value;
            reader.Read();
            var ratings = ((JArray)serializer.Deserialize(reader)).Values<string>("rating");
            movie.MovieInfo.Add(name, ratings.Select(r => new MovieRating(){ Rating = r}).ToList());
        }
        return movie;
    }
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

我确实需要对您的原始对象进行两次更改,第一次我将MovieInfo的访问器设置为公共的,以便可以访问它,第二次添加JsonConverterAttribute:

[JsonConverter(typeof(MovieConverter))]
public class Movie
{
    public IDictionary<string, IList<MovieRating>> MovieInfo { get; set; }
}

相关内容

  • 没有找到相关文章

最新更新