Arhn - архитектура программирования

Сопоставление свойств со списком объектов

У меня есть данные JSON, которые выглядят так:

{
    "Item1": {
        "Field1": "Val1",
        "Field2": "Val2"
    },
    "Item2": {
        "Field1": "Val11",
        "Field2": "Val22"
    },
    ....
    "ItemN": {
        "Field1": "Val1",
        "Field2": "Val2"
    },
}

Мне нужно десериализовать его в набор классов, которые выглядят так:

public class Root
{
    public Item Item1;
    public Item Item2;

    public List<Item> Items; // << all the Items should go here
}

public class Item
{
    public string Field1;
    public string Field2;
}

Как я могу заставить Newtonsoft.Json отображать данные таким образом при десериализации?

16.08.2017


Ответы:


1

Если вам нужно заполнить список Items и отдельные свойства Item, показанные в вашем классе Root, из одних и тех же данных в формате JSON, вам потребуется собственный JsonConverter, чтобы сделать это. Должен работать следующий преобразователь:

public class RootConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(Root);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        JObject obj = JObject.Load(reader);
        var root = new Root();

        // populate all known Root properties 
        serializer.Populate(obj.CreateReader(), root);

        // populate Items list with all objects that can be converted to an Item
        root.Items = obj.Properties()
                        .Where(p => p.Value.Type == JTokenType.Object && 
                                    (p.Value["Field1"] != null || p.Value["Field2"] != null))
                        .Select(p => p.Value.ToObject<Item>())
                        .ToList();
        return root;
    }

    public override bool CanWrite
    {
        get { return false; }
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

Затем, чтобы использовать его, добавьте атрибут [JsonConverter] к вашему классу Root следующим образом:

[JsonConverter(typeof(RootConverter))]
public class Root
{
    public Item Item1 { get; set; }
    public Item Item2 { get; set; }

    public List<Item> Items; // << all the Items should go here
}

Скрипт: https://dotnetfiddle.net/aADhzw

03.08.2020
  • Мне нужен корневой класс для статического отображения некоторых свойств. 03.08.2020
  • Интересно, есть ли способ не выполнять сопоставление свойств вручную? 04.08.2020
  • Конечно, вы можете использовать Populate; см. обновленный ответ. 04.08.2020

  • 2

    Нет необходимости в классе Root. Я бы десериализовал в словарь

    var dict= JsonConvert.DeserializeObject<Dictionary<string, Item>>(json);
    
    16.08.2017
  • Вы можете немного порадовать? как он сопоставит массив объектов JS со словарем и что здесь будет делать десериализация? 25.06.2018

  • 3

    Из сообщения @L.B: если вам нужна работа с корневым объектом, вы можете попробовать это так:

    public class Root : Dictionary<string, Item>
    {
        public List<Item> Items => this.Values.ToList();
    }
    

    Затем вы можете десериализовать JSON в корневой объект:

     var root = JsonConvert.DeserializeObject<Root>(json);
    
    08.08.2020

    4

    Использовать:

    public class Root
    {
        public List<Item> Items {get;set;}
    }
    public class Item
    {
        public string Field1 {get;set;}
        public string Field2; {get;set;}
    }
    

    Как классы, так и вызов:

    Root foobar = new JavaScriptSerializer().Deserialize<Root>(result);
    

    Для десериализации.

    16.08.2017
    Новые материалы

    Коллекции публикаций по глубокому обучению
    Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

    Представляем: Pepita
    Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

    Советы по коду Laravel #2
    1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

    Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
    Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

    3 способа решить квадратное уравнение (3-й мой любимый) -
    1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

    Создание VR-миров с A-Frame
    Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

    Демистификация рекурсии
    КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..