Преобразование идентификатора вложенного объекта в объект при десериализации JSON

*** Обновлено: уточнено, что есть два отдельных файла JSON ***

У меня есть два класса:

public class Phone  
{
     public int PhoneId  { get; set; }
     public string Name { get; set; }
     public Manufacturer PhoneManufacturer { get; set; }
}

public class Manufacturer  
{
    public int ManId  { get; set; }
    public string Name  { get; set; }
}

И два файла JSON, содержащие данные для обоих классов:

Телефоны.json:

[
   {
       "phoneId" : 45,
       "name": "S20",
       "phoneManufacturer":16
   }
]

Производители.json:

[
   {
       "manId" : 16,
       "name": "Samsung"      
   }
]

Я использую следующий код для десериализации объектов телефонов:

string jsonString = File.ReadAllText("phones.json");
return JsonSerializer.Deserialize<List<Phone>>(jsonString, new JsonSerializerOptions { PropertyNameCaseInsensitive = true})!;

Я хочу, чтобы при десериализации JSON телефонов в List<Phone> свойство PhoneManufacturer результирующих объектов было заполнено фактическим объектом Manufacturer.

При запуске десериализации с параметрами по умолчанию я получаю ошибку, что JSON не может преобразовать значение в свойстве PhoneManufacturer в объект Manufacturer, что имеет смысл, поскольку это идентификатор объекта, а не сам объект.

Как я могу этого добиться?

У результирующих объектов свойство PhoneManufacturer будет заполнено фактическим объектом Manufacturer. Я не думаю, что у вас есть правильный файл json.

Soner from The Ottoman Empire 11.01.2023 06:34

Как выглядит jsonString? Можете ли вы изменить данные JSON, чтобы они соответствовали структуре класса C Sharp?

Charles Han 11.01.2023 06:36

Ваш JSON выглядит как неправильный/хороший формат

MichaelMao 11.01.2023 06:45

Я отредактировал вопрос, чтобы внести ясность. Есть два файла JSON, а переменная jsonString хранит содержимое файла phone.json.

ml123 11.01.2023 06:57
Типы данных JavaScript
Типы данных JavaScript
В JavaScript существует несколько типов данных, включая примитивные типы данных и ссылочные типы данных. Вот краткое объяснение различных типов данных...
Как сделать движок для футбольного матча? (простой вариант)
Как сделать движок для футбольного матча? (простой вариант)
Футбол. Для многих людей, живущих на земле, эта игра - больше, чем просто спорт. И эти люди всегда мечтают стать футболистом или менеджером. Но, к...
Знайте свои исключения!
Знайте свои исключения!
В Java исключение - это событие, возникающее во время выполнения программы, которое нарушает нормальный ход выполнения инструкций программы. Когда...
CSS Flex: что должен знать каждый разработчик
CSS Flex: что должен знать каждый разработчик
CSS Flex: что должен знать каждый разработчик Модуль flexbox, также известный как гибкий модуль разметки box, помогает эффективно проектировать и...
Введение в раздел &quot;Заголовок&quot; в HTML
Введение в раздел "Заголовок" в HTML
Говорят, что лучшее о человеке можно увидеть только изнутри, и это относится и к веб-страницам HTML! Причина, по которой некоторые веб-страницы не...
0
4
59
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Вам нужно написать собственный преобразователь для ручного сопоставления идентификаторов с объектами. Существует отличная серия статей, посвященных этой теме как для NewtonSoft, так и для System.Text.Json: Работа с сериями JSON. Раздел, помеченный Multi-Value Type Collections, похож на то, что вы пытаетесь сделать.

Ответ принят как подходящий

Если вы используете System.Text.Json и не возражаете против изменения класса для добавления нового конструктора, это вполне достижимо, если у вас есть коллекция производителей, доступных для конструктора Phone. Что-то вроде:

[JsonConstructor]
public Phone(int phoneId, string name, int phoneManufacturer)
{
    PhoneId = phoneId;
    Name = name;
    if (!ManufacturerDictionary.Contains(phoneManufacture)) throw new Exception();
    PhoneManufacturer = ManufacturerDictionary.[phoneManufacturer];
} 

О, и сначала загрузите Manufacturers.json 😉

Andy Wynn 11.01.2023 07:10

Вы можете попробовать этот код

var phonesJsonArr = JsonNode.Parse(phonesJson).AsArray();

var manufacturersJsonArr = JsonNode.Parse(manufacturersJson).AsArray();

    foreach (JsonNode node in phonesJsonArr)
    {
        var manId = node["phoneManufacturer"].GetValue<int>();
        node["PhoneManufacturer"] = new JsonObject
        {

            ["manId"] = manId,
            ["Name"] = manufacturersJsonArr.Where(ja => ja["manId"].GetValue<int>() == manId).Select(ja => ja["name"].GetValue<string>()).FirstOrDefault()

        };
         node.AsObject().Remove("phoneManufacturer");
     }

List<Phone> phones = phonesJsonArr.Deserialize<List<Phone>>(new JsonSerializerOptions { PropertyNameCaseInsensitive = true});

Другие вопросы по теме