【问题标题】:What is wrong with this JSON file? Can't be deserialized这个 JSON 文件有什么问题?无法反序列化
【发布时间】:2020-06-14 14:57:14
【问题描述】:

我有一个 JSON 文件的问题,它是一个国家对象列表,如下所示:

{
    "Countries": [
        {
            "Code": "AFG",
            "Name": "Afghanistan",
            "Population": 38928346
        },
        {
            "Code": "ALA",
            "Name": "Åland Islands",
            "Population": 28007
        },
        {
            "Code": "ALB",
            "Name": "Albania",
            "Population": 2877797
        },
        {
            "Code": "DZA",
            "Name": "Algeria",
            "Population": 43851044
        },
        {
            "Code": "ASM",
            "Name": "American Samoa",
            "Population": 55191
        }
    ]
}

我正在尝试使用此代码来读取它并将其反序列化为 List 对象:

Stream? countriesResourceStream = Assembly.GetExecutingAssembly().GetManifestResourceStream("MyProject.Countries.json");

if (countriesResourceStream == null)
{
    return;
}

var countries = new List<Country>();

using (StreamReader reader = new StreamReader(countriesResourceStream))
{
    var serializer = new JsonSerializer();
    countries = serializer.Deserialize<List<Country>>(new JsonTextReader(reader));
}

但是 serializer.Deserialize 方法抛出异常:

'无法将当前 JSON 对象(例如 {"name":"value"})反序列化为类型 'System.Collections.Generic.List`1[MyProject.Models.EntityFramework.Country]',因为该类型需要 JSON数组(例如 [1,2,3])以正确反序列化。 要修复此错误,请将 JSON 更改为 JSON 数组(例如 [1,2,3])或更改反序列化类型,使其成为普通的 .NET 类型(例如,不是像整数这样的原始类型,而不是像可以从 JSON 对象反序列化的数组或列表。 JsonObjectAttribute 也可以添加到类型中,以强制它从 JSON 对象反序列化。

我的 JSON 有什么问题?我已经尝试过 Newtonsoft 和 System.Text.Json。

【问题讨论】:

  • 这不是 JSON 本身的问题,除非它与您要反序列化的 .net 数据类型不匹配。
  • 您似乎在告诉它 JSON 应该是 Country 对象列表,但事实并非如此;它是具有 Country 值的顶级对象; that 值映射到对象列表。如果您使 JSON 文件以 [ 开始并以 ] 结束,则该代码可能会起作用。 (“大概”是因为这不是 minimal reproducible example 不包括 Country 的定义,所以我们无法测试我们的答案)。

标签: json json.net json-deserialization


【解决方案1】:

问题在于您的 JSON 不代表国家/地区列表,它代表一个包含国家/地区列表的对象。你需要另一个类:

class CountryListContainer
{
    public List<Country> Countries { get; set; }
}

反序列化到容器类中,然后您可以从中获取您的国家/地区列表:

using (StreamReader streamReader = new StreamReader(countriesResourceStream))
using (JsonTextReader jsonReader = new JsonTextReader(streamReader))
{
    var serializer = new JsonSerializer();
    countries = serializer.Deserialize<CountryListContainer>(jsonReader).Countries;
}

小提琴:https://dotnetfiddle.net/5DM4il


或者,您可以按照@Charles Duffy 在 cmets 中的建议更改您的 JSON。如果 JSON 看起来像这样(没有外部对象),那么您现有的代码就可以工作:

[
  {
    "Code": "AFG",
    "Name": "Afghanistan",
    "Population": 38928346
  },
  {
    "Code": "ALA",
    "Name": "Åland Islands",
    "Population": 28007
  },
  {
    "Code": "ALB",
    "Name": "Albania",
    "Population": 2877797
  },
  {
    "Code": "DZA",
    "Name": "Algeria",
    "Population": 43851044
  },
  {
    "Code": "ASM",
    "Name": "American Samoa",
    "Population": 55191
  }
]

小提琴:https://dotnetfiddle.net/gMHhcX

【讨论】:

  • 谢谢你,布赖恩,你让我的一天变得更轻松了,现在它正在工作,上帝知道我需要它。我选择了第二个选项,我不想要一个包含 List 的“Countries”对象,但显然我的线路与 JSON 交叉。
  • 很高兴我能帮上忙。
猜你喜欢
  • 2017-10-23
  • 2021-09-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多