skip to Main Content

*** Edit: Clarified there are two, separate JSON files ***

I have two classes:

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; }
}

And two JSON files containing data for both classes:

phones.json:

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

manufacturers.json:

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

I use the following code to deserialize the phones objects:

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

I want that when deserializing the Phones JSON to List<Phone>, the resulting objects will have its PhoneManufacturer property populated with the actual Manufacturer object.

When running the deserialization with the default parameters, I get an error that JSON cannot convert the value in the PhoneManufacturer property to a Manufacturer object, which makes sense since this is the object Id, and not the object itself.

How can I achieve that?

3

Answers


  1. You need to write a custom converter for manually mapping IDs to objects. There is a great series of Articles that cover this topic for both NewtonSoft & System.Text.Json: Working with JSON Series. The section labelled Multi-Value Type Collections is similar to what you are trying to do.

    Login or Signup to reply.
  2. If you are using System.Text.Json, and you don’t mind modifying the class to add a new constructor, this is quite achievable as long as you have a collection of manufacturers available to the Phone constructor.
    Something like:

    [JsonConstructor]
    public Phone(int phoneId, string name, int phoneManufacturer)
    {
        PhoneId = phoneId;
        Name = name;
        if(!ManufacturerDictionary.Contains(phoneManufacture)) throw new Exception();
        PhoneManufacturer = ManufacturerDictionary.[phoneManufacturer];
    } 
    
    Login or Signup to reply.
  3. you can try this code

    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});
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search