Ошибка при десериализации из json [дубликат]

227
26 мая 2018, 03:20

На данный вопрос уже ответили:

  • Как распарсить json в ассоциативный массив / C# 3 ответа

Есть json.

{
    "1": {
        "m": "StatTrak™ AK-47 | Blue Laminate (Field-Tested)",
        "c": 1,
        "g": 3,
        "z": 2,
        "e": "FT",
        "v": 20,
        "h": 4,
        "u": "kxu",
        "w": 1,
        "j": "StatTrak™ AK-47 | Синий глянец (После полевых испытаний)"
    },
    "2": {
        "m": "StatTrak™ P250 | Valence (Field-Tested)",
        "c": 1,
        "g": 5,
        "z": 1,
        "e": "FT",
        "v": 13,
        "h": 2,
        "u": "kwd",
        "w": 31,
        "j": "StatTrak™ P250 | Валентность (После полевых испытаний)"
    }
}

Преобразовал его в класс

public class Data
{
    public string m { get; set; }
    public int c { get; set; }
    public int g { get; set; }
    public int z { get; set; }
    public string e { get; set; }
    public int v { get; set; }
    public int h { get; set; }
    public string u { get; set; }
    public int w { get; set; }
    public string j { get; set; }
}
public class RootObject
{
    public Data[] data { get; set; }
}

При попытке сериализации выдает ошибку

var res = js.Deserialize<Data[]>(json)

Для типа "WindowsFormsApp21.Data[]" не определен конструктор без параметров."

Answer 1

Способ первый самый простой

Когда нужны все данные из json.

public class Data
{
    public string m { get; set; }
    /* куча проперти */
}
var  data = JsonConvert.DeserializeObject<Dictionary<string, Data>>(json)

Почему тип Dictionary<string, Data>, т.к. у вас именно JObject идет первым (как я это определил ниже), то все элементы на его верхнем уровне считаются JProperty. У каждого есть имя и значение, где в качестве значения может быть друга вложенная структура данных. В нашем случае словарь по сути это массив этих самых JProperty, где key=имя проперти и value=значение.

Как я опередил что это JObject. Первый уровень не имеет ни одного JProperty и начинается с фигурных скобок. Пример ниже будет уже считаться JArray. Такой формат библиотека newtonsoft считает массивом.

{
    [{
        "m": "StatTrak™ AK-47 | Blue Laminate (Field-Tested)",
        "c": 1
    },
    {
        "m": "StatTrak™ P250 | Valence (Field-Tested)",
        "c": 1
    }]
}

Разбор в словарь также подходит для случаев, когда ваш json имеет похожую структуру, но поля разные. Например как здесь.

[
    {
        "filterType": "PRICE_FILTER",
        "minPrice":"0.01000000",
        "maxPrice":"10000000.00000000",
        "tickSize":"0.01000000"
    },
    {
        "filterType":"LOT_SIZE",
        "minQty":"0.00001000",
        "maxQty":"10000000.00000000",
        "stepSize":"0.00001000"
    },
    {
        "filterType":"MIN_NOTIONAL",
        "minNotional":"10.00000000"
    }
]

В таком случае вам не нужно будет создавать один класс со всеми этими полями.

var  data = JsonConvert.DeserializeObject<List<Dictionary<string, string>>>(json)

В случае если все таки решитесь на отдельный класс, то все проперти, которые не будут найдены в json останутся инициализированы по дефолту.

Второй вариант, но мудренее

var data = JObject.Parse(a)
    .SelectTokens("$.*")
    .Select(o => o.ToObject<Data>())
    .ToArray();

Переменная data будет типом Data[], но значения 1,2 будут потеряны. Этот вариант применим, когда исходный json очень большой и имеет сложную структуру, вам не нужны все данные из него, то делать структуру 1 в 1 неразумно. В этом случае можно вытащить с помощью xpath нужные элементы. Xpath это путь до элемета/ов. Работает по такому же принципу, как select запрос в бд. С его помощью можно указать путь и условия по которым вы хотите собрать данные.

  • С помощью этого сайта можно практиковать xpath запросы для json структуру
  • А с помощью этого можно получать структуры, которые будет соответствовать вашему json.
  • Здесь можно почитать о всех фишках библиотеки Newtonsoft
READ ALSO
Невозможно записать или создать файл - С# .NET Core + UWP

Невозможно записать или создать файл - С# .NET Core + UWP

Всем доброго времени суток! Есть проблема, мне выбивает такую ошибку:

249
При задании значения в своём свойстве в xaml оно всегда null в конструкторе контрола

При задании значения в своём свойстве в xaml оно всегда null в конструкторе контрола

Добавляю своё свойство в контрол, чтобы его можно было задавать через xaml

215
Возможно ли вызывать функцию из C# в JS

Возможно ли вызывать функцию из C# в JS

Возможно ли зарегистрировать функцию в C#, и передать её в ChromiumДопустим, есть функция на C# , которая будет выглядеть так:

237
WPF ComboBox + MVVM, запрос при выборе элемента

WPF ComboBox + MVVM, запрос при выборе элемента

В процессе работы над проектом возникла необходимость сделать ComboBox при выборе элемента которого выдавался бы запрос, Вроде - "А Вы уверены?",...

214