У меня проблема с файлом 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.

0
ataraxia 14 Июн 2020 в 17:57

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


В качестве альтернативы вы можете изменить свой JSON, как @Charles Duffy предложил в комментариях. Если бы 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

1
Brian Rogers 14 Июн 2020 в 15:43