【问题标题】:JSON deserialization not deserializing?JSON反序列化不反序列化?
【发布时间】:2016-12-11 23:21:01
【问题描述】:

我对 JSON 字符串的序列化/反序列化有点陌生。我曾尝试使用 Newtonsoft.Json。问题是我收到了 JSON 字符串 url : http://epguides.frecar.no/show/gameofthrones/ 我想从中创建和分类对象。所以以后我可以打印出来...

我发现了如何通过复制字符串和 Edit>Paste_Special>Paste_JSON_as_Classes 从您的 JSON 字符串生成类,这样应该没问题。

生成的类:

namespace TvSeries
{

public class Show
{
    public string title { get; set; }
    public string imdb_id { get; set; }
    public string epguide_name { get; set; }
}

public class __invalid_type__1
{
    public Show show { get; set; }
    public string title { get; set; }
    public int number { get; set; }
    public int season { get; set; }
    public string release_date { get; set; }
}

public class Show2
{
    public string title { get; set; }
    public string imdb_id { get; set; }
    public string epguide_name { get; set; }
}

public class __invalid_type__2
{
    public Show2 show { get; set; }
    public string title { get; set; }
    public int number { get; set; }
    public int season { get; set; }
    public string release_date { get; set; }
}

public class Show3
{
    public string title { get; set; }
    public string imdb_id { get; set; }
    public string epguide_name { get; set; }
}

public class __invalid_type__3
{
    public Show3 show { get; set; }
    public string title { get; set; }
    public int number { get; set; }
    public int season { get; set; }
    public string release_date { get; set; }
}

public class Show4
{
    public string title { get; set; }
    public string imdb_id { get; set; }
    public string epguide_name { get; set; }
}

public class __invalid_type__4
{
    public Show4 show { get; set; }
    public string title { get; set; }
    public int number { get; set; }
    public int season { get; set; }
    public string release_date { get; set; }
}

public class Show5
{
    public string title { get; set; }
    public string imdb_id { get; set; }
    public string epguide_name { get; set; }
}

public class __invalid_type__5
{
    public Show5 show { get; set; }
    public string title { get; set; }
    public int number { get; set; }
    public int season { get; set; }
    public string release_date { get; set; }
}

public class Show6
{
    public string title { get; set; }
    public string imdb_id { get; set; }
    public string epguide_name { get; set; }
}

public class __invalid_type__6
{
    public Show6 show { get; set; }
    public string title { get; set; }
    public int number { get; set; }
    public int season { get; set; }
    public string release_date { get; set; }
}

public class Show7
{
    public string title { get; set; }
    public string imdb_id { get; set; }
    public string epguide_name { get; set; }
}

public class __invalid_type__7
{
    public Show7 show { get; set; }
    public string title { get; set; }
    public int number { get; set; }
    public int season { get; set; }
    public string release_date { get; set; }
}

public class RootObject
{
    public List<__invalid_type__1> __invalid_name__1 { get; set; }
    public List<__invalid_type__2> __invalid_name__2 { get; set; }
    public List<__invalid_type__3> __invalid_name__3 { get; set; }
    public List<__invalid_type__4> __invalid_name__4 { get; set; }
    public List<__invalid_type__5> __invalid_name__5 { get; set; }
    public List<__invalid_type__6> __invalid_name__6 { get; set; }
    public List<__invalid_type__7> __invalid_name__7 { get; set; }
}

}

这是一个简单的主类,可以将其打印到控制台:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Web.Script.Serialization;
using Newtonsoft.Json;

namespace TvSeries
{
    class Program
    {
        static void Main(string[] args)
        {
            using (WebClient wc = new WebClient())
            {
                var json = wc.DownloadString("http://epguides.frecar.no/show/gameofthrones/");
                //Console.WriteLine(json);
                RootObject obj = JsonConvert.DeserializeObject<RootObject>(json);
                foreach (var item in obj.__invalid_name__1)
                {
                    Console.WriteLine("Show: {0}, release date: {1}", item.show.title, item.release_date);
                } 
                Console.ReadKey();
            }
        }
    }
}

所以实际的问题是为什么没有反序列化或正常工作,因为对象仍然是 null?我错过了一些重要的东西?我也试过 JavaScriptSerializer() 但它不能解决我的问题。

【问题讨论】:

  • 你有一大堆具有相同名称的类(show1 / show2 等)。这是由 vs 创建的相当愚蠢的,因为您从中粘贴的 json 返回一个节目列表,并且对于每个列表元素,vs 为它创建了一个不同的类。简化类。我还假设“无效类型”类适用于Episode。整理类和 jsonconvert 将按照您的期望自动填充您的对象。它目前正在返回 null,因为它无法反序列化。
  • 根据您想要对数据执行的操作,您甚至可以在不生成类的情况下反序列化为 dynamic 对象。
  • 你没有注意到你有一堆名为__invalid_type__n的类型吗?这应该会给你一个指示。

标签: c# json json.net deserialization


【解决方案1】:

你使用这样的属性:

[JsonProperty("show")]
public Show2 Show2 { get; set; }

【讨论】:

    【解决方案2】:

    正如 user3791372 所说,您应该整理生成的类。然而,这些类是生成的,因为响应看起来像这样 { "1":[{...}...], "2":[{...}...],...}。因此,您首先需要摆脱“1”、“2”,并为干净的代码定义自己的类型。结果将如下所示

    class Show
    {
        public string title { get; set; }
        public string imdb_id { get; set; }
        public string epguide_name { get; set; }
    }
    
    class Episode
    {
        public Show show { get; set; }
        public string title { get; set; }
        public int number { get; set; }
        public int season { get; set; }
        public DateTime release_date { get; set; }
    }
    
    class Program
    {
        static void Main(string[] args)
        {
            using (WebClient wc = new WebClient())
            {
                //download json string
                var json = wc.DownloadString("http://epguides.frecar.no/show/gameofthrones/");
                //convert json to dynamic object
                JObject obj = JObject.Parse(json);
                //create an array that have as many elements as the children of obj => {"1", "2", "3", ...}
                JArray[] results = new JArray[obj.Children().Count()];
                //fill the array with the children of obj => results[6] = "[{"show": {"title": "Game of Thrones", "imdb_id": "tt0944947", "epguide_name": "gameofthrones"}, "title": "TBA", "number": 1, "season": 7, "release_date": "2017-06-25"}]"
                for (int i = 0; i < results.Length; i++)
                {
                    results[i] = (JArray)obj[(i + 1).ToString()];
                }
                //deserialize each item in results to List<Episode> if you checked the response it returns arrays of episodes
                List<List<Episode>> seasons = new List<List<Episode>>(results.Length);
                foreach (var item in results)
                {
                    seasons.Add(JsonConvert.DeserializeObject<List<Episode>>(item.ToString()));
                }
                //output the result
                foreach (var season in seasons)
                {
                    foreach (var episod in season)
                    {
                        Console.WriteLine("Show: {0}, release date: {1}", episod.show.title, episod.release_date);
                    }
                }
                Console.ReadKey();
            }
    
        }
    }
    

    【讨论】: