【问题标题】:Deserialing to list of object反序列化到对象列表
【发布时间】:2019-11-20 15:52:04
【问题描述】:

需要使用 newtonsoft.json.net 反序列化这个 JSON:

{
  "dataset": {
    "id": 36592406,
    "dataset_code": "EON_X",
    "database_code": "FSE",
    "start_date": "2019-11-18",
    "end_date": "2019-11-18",
    "data": [
      [
        "2019-11-18",
        9.17,
        9.204,
        9.121,
        9.167,
        null,
        6088172.0,
        55793844.0,
        null,
        null,
        null
      ]
    ]

  }
}

List<FseItem>。问题是我只需要“数据”部分。我试图用这个:

            var settings = new JsonSerializerSettings
            {
                NullValueHandling = NullValueHandling.Ignore,
                MissingMemberHandling = MissingMemberHandling.Ignore
            };

            var json = GetResult(url);
            var obj = JsonConvert.DeserializeObject<List<FseItem>>(json, settings);

这是我的 FseItem 对象:

        public class FseItem
        {
            public DateTime Date { get; set; }
            public decimal Open { get; set; }
            public decimal High { get; set; }
            public decimal Low { get; set; }
            public decimal Close { get; set; }
            public decimal Change { get; set; }
            public decimal TradedVolume { get; set; }
            public decimal TurnOver { get; set; }
            public decimal LastPrice { get; set; }
            public decimal TradedUnits { get; set; }
            public decimal DailyTurnover { get; set; }
        }

但我收到此错误: Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[InvestorWeb2.WebUI.Domain.QwertyReporting.FseReport+FseItem]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.

我从 Quandl 免费数据库中获取我的 JSON,因此我无法更改 json 数据中的任何内容。在此示例中,json 仅包含一个元素,但我也将使用大型 json 文件。我的代码有什么问题,我应该怎么做才能解决它们?

对于大量数据的快速解决方案以及关于解析和使用大 json 的一些建议将不胜感激!

【问题讨论】:

  • 这甚至是有效的 json 吗? JSONLint 说它不是...
  • 所有不同的 json 规范都失败了,它是无效的 json。由于您是从另一个地方获取数据,我会让他们知道这是错误的并且需要修复。如果您从底部的], 中删除,,它将通过rfc 8259 规范。
  • 只有部分 JSON 文本表示一个数组,但您的代码将整个内容视为一个集合/数组。 Start your research here
  • 请检查您的 json,因为它无效,我想您忘记删除逗号了。
  • 我的错,我删除了一些数据以使我的示例更简单。我编辑了json,所以它是有效的atm。但是在反序列化时尝试获取对象列表时仍然出错

标签: c# json serialization


【解决方案1】:

好的,我研究了几个不同的信息,这就是我发现的:

首先我需要为我的整个 JSON 使用 RootObject,所以我添加了更多对象:

 public class RootObject
        {
            [JsonProperty("dataset_data")]
            public Dataset dataset_data { get; set; }
        }

        public class Dataset
        {
            [JsonProperty("frequency")]
            public string frequency { get; set; }

            [JsonProperty("start_date")]
            public DateTime start_date { get; set; }

            [JsonProperty("end_date")]
            public DateTime end_date { get; set; }

            [JsonProperty("data")]
            public List<FseItem> data { get; set; }
        }

问题是我的 JSON 数组没有为他的元素命名。看起来将数组反序列化为对象的唯一方法是使用转换器:

[JsonConverter(typeof(FseItemConverter))]
        public class FseItem
        {
            public DateTime Date { get; set; }
            public decimal? Open { get; set; }
            public decimal? High { get; set; }
            public decimal? Low { get; set; }
            public decimal? Close { get; set; }
            public decimal? Change { get; set; }
            public decimal? TradedVolume { get; set; }
            public decimal? TurnOver { get; set; }
            public decimal? LastPrice { get; set; }
            public decimal? TradedUnits { get; set; }
            public decimal? DailyTurnover { get; set; }
        }


 public class FseItemConverter : JsonConverter
    {

        public override bool CanConvert(Type objectType)
        {
            return objectType.Name.Equals("FseItem");
        }

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {

            JArray array = JArray.Load(reader);
            return new FseReport.FseItem
            {
                Date = array[0].ToObject<DateTime>(),
                Open = array[1].ToObject<decimal?>(),
                High = array[2].ToObject<decimal?>(),
                Low = array[3].ToObject<decimal?>(),
                Close = array[4].ToObject<decimal?>(),
                Change = array[5].ToObject<decimal?>(),

                TradedVolume = array[6].ToObject<decimal?>(),
                TurnOver = array[7].ToObject<decimal?>(),
                LastPrice = array[8].ToObject<decimal?>(),
                TradedUnits = array[9].ToObject<decimal?>(),
                DailyTurnover = array[10].ToObject<decimal?>()

            };
        }

        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            var orderItem = value as FseReport.FseItem;
            JArray arra = new JArray();
            arra.Add(orderItem.Date);
            arra.Add(orderItem.Open);
            arra.Add(orderItem.High);
            arra.Add(orderItem.Low);
            arra.Add(orderItem.Close);
            arra.Add(orderItem.Change);
            arra.Add(orderItem.TradedVolume);
            arra.Add(orderItem.TurnOver);
            arra.Add(orderItem.LastPrice);
            arra.Add(orderItem.TradedUnits);
            arra.Add(orderItem.DailyTurnover);

            arra.WriteTo(writer);
        }
    }

另外,说到大的 JSON 数据,最好使用 StreamJsonReader,而不是 string 从 URL 读取 json 数据:

HttpClient client = new HttpClient();

            using (Stream s = client.GetStreamAsync(url).Result)
            using (StreamReader sr = new StreamReader(s))
            using (JsonReader reader = new JsonTextReader(sr))
            {
                JsonSerializer serializer = new JsonSerializer();

                var result = serializer.Deserialize<RootObject>(reader);

                return result.dataset_data.data;
            }

希望这些信息对某些人有所帮助。也许有一些方法可以改善这一点,但它对我有用,所以我会在这里发布它

【讨论】:

  • 对于 RootObject 的另一个好技巧是在 Visual Studio 中使用“Paste Special”(编辑 -> 粘贴特别 -> 将 JSON 粘贴到类)。它将使用代码生成从 JSON 代码生成 C# 类。非常舒适的反序列化选项
  • 另外,如何在没有转换器的情况下制作它的另一种方法,您可以在这个问题中找到:link
猜你喜欢
  • 1970-01-01
  • 2020-10-31
  • 2020-11-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-10
  • 2018-08-17
相关资源
最近更新 更多