skip to Main Content

Im trying to deserialize a List of Holograms from a json file. The List of Holograms can contain HologramGroup, that is a derived class of Hologram. I’m trying to use a JsonConverter to do this. I want to check if a Hologram contains the property "holograms". If this is the case, this Hologram should be returned as HologramGroup.

The Converter:

public class MyJsonConverter : JsonConverter<Hologram>
    {
        public override Hologram ReadJson(JsonReader reader, Type objectType, Hologram existingValue, bool hasExistingValue, JsonSerializer serializer)
        {
            JObject root = JObject.Load(reader);

            if (root.TryGetValue("holograms", out var type))
            {
                return root.ToObject<HologramGroup>();
            }

            return root.ToObject<Hologram>();
        }

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

Classes:

    [JsonConverter(typeof(ArJsonConverter))] //<- Im hoping to use the converter for all Holograms in my JSON. Not sure if this is the right approach.
    public class Hologram
    {
        public string HologramType { get; set; }
        public List<HologramProperty> Properties { get; set; }
    }


    public class HologramGroup : Hologram
    {
        public List<Hologram> Holograms { get; set; }
    }

    public class Scene
    {
        public string Name { get; set; }
        public List<Hologram> Holograms { get; set; }
    }

JSON to deserialize:

{
  "name": "MyScene",
  "holograms": [
    {
      "hologramType": "Video",    
      "properties": []
    },
    {
      "hologramType": "Picture",    
      "properties": []
    },
    {
      "hologramType": "HologramGroup",    
      "properties": [],
      "holograms": [
        {
          "hologramType": "Model3D",        
          "properties": []
        },
        {
          "hologramType": "Model3D",        
          "properties": []
        }     
      ]
    }
  ]
}

This code makes my Application crash and I’m not quite sure why. Polymorphism is quite new for me and I could use some help.

2

Answers


  1. try this:

    [JsonConverter(typeof(MyJsonConverter))]
    public class Hologram
    {
        public string HologramType { get; set; }
        public List<HologramProperty> Properties { get; set; }
    }
    
    public class HologramGroup : Hologram
    {
        public List<Hologram> Holograms { get; set; }
    }
    
    public class Scene
    {
        public string Name { get; set; }
        public List<Hologram> Holograms { get; set; }
    }
    
    public class MyJsonConverter : JsonConverter<Hologram>
    {
        public override Hologram ReadJson(JsonReader reader, Type objectType, Hologram existingValue, bool hasExistingValue, JsonSerializer serializer)
        {
            JObject root = JObject.Load(reader);
    
            if (root.TryGetValue("holograms", out var _))
            {
                HologramGroup group = new HologramGroup();
                serializer.Populate(root.CreateReader(), group);
                return group;
            }
    
            Hologram hologram = new Hologram();
            serializer.Populate(root.CreateReader(), hologram);
            return hologram;
        }
    
        public override void WriteJson(JsonWriter writer, Hologram value, JsonSerializer serializer)
        {
            throw new NotImplementedException();
        }
    }
    
    Login or Signup to reply.
  2. if you add a constructor, you don’t need any converter

    public class Scene
    {
        public string name { get; set; }
        public List<Hologram> holograms { get; set; }
    
        public Scene(JArray holograms)
        {
        this.holograms = holograms.Select(ho => (string)ho["hologramType"] == "HologramGroup"
                    ? ho.ToObject<HologramGroup>()
                    : ho.ToObject<Hologram>()).ToList();
        }
    }
    
    

    or if you prefer a converter

    public class Scene
    {
        public string name { get; set; }
    
        [JsonConverter(typeof(GroupConverter))]
        public List<Hologram> holograms { get; set; }
    }
    public class GroupConverter : JsonConverter<List<Hologram>>
    {
        public override List<Hologram> ReadJson(JsonReader reader, Type objectType, List<Hologram> existingValue, bool hasExistingValue, JsonSerializer serializer)
        {
        return JArray.Load(reader)
                     .Select(ho => (string)ho["hologramType"] == "HologramGroup"
                    ? ho.ToObject<HologramGroup>()
                    : ho.ToObject<Hologram>()).ToList();
        }
    
        public override void WriteJson(JsonWriter writer, List<Hologram> value, JsonSerializer serializer)
        {
            throw new NotImplementedException();
        }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search