0

I have to consume a Rest API where the content has variable structure in a child list ..

Here is a simplified representation that a Small Car has several components:- Window, Engine and Door

{
   "ProductCode": 1234,
   "ProductName": "SmallCar",
   "Components": [
      {
          "PartType": "Window",
          "Operation": "Electric",
          "Tinted": true,
      },
      {
          "PartType": "Engine",
          "Capacity": 2000,
          "Cylinders": 6,
          "Layout": "V6"
      },
      {
          "PartType": "Door",
          "DoorStyle": "Standard"
      }
   ]
}

My POCO classes are defined as below:-

public class Product
{
    public int ProductCode {get; set;}
    public string ProductName {get; set;}
    public List<Component> Components {get; set;}
}

public class Component
{
    public string PartType {get; set;}
}

public class Window : Component
{
    public string Operation {get; set;}
    public bool Tinted {get; set;}
}

public class Engine : Component
{
    public int Capacity {get; set;}
    public int Cylinders {get; set;}
    public string Layout {get; set;}
}

public class Door : Component
{
    public string DoorStyle {get; set;}
}

During the deserialization, how can I get it to create the appropriate component object (Window, Door, Engine). With var product = DeserializeObject<Product>(....) I just get a list of Components with PartType set, but I need the list to be of each class type according to the PartType

Chris Hammond
  • 2,064
  • 5
  • 27
  • 53
  • You will need to implement a custom converter for `PartType`. and then you could use `JsonConverter(typeof(CustomPartTypeConverter))` on that property. – iSR5 Jul 01 '22 at 12:06
  • Can you control the serialization? If not, I would manually map depending on Component.PartType. – Lzh Jul 01 '22 at 12:08
  • 1
    Could maybe [this](https://stackoverflow.com/questions/8513042/json-net-serialize-deserialize-derived-types) help you ? – Michalor Jul 01 '22 at 12:11
  • You can create a custom [`JsonConverter`](https://www.newtonsoft.com/json/help/html/CustomJsonConverter.htm) to deserialize your class hierarchy. Please see [Deserializing polymorphic json classes without type information using json.net](https://stackoverflow.com/q/19307752/3744182), [Json.Net Serialization of Type with Polymorphic Child Object](https://stackoverflow.com/q/29528648/3744182) or [How to implement custom JsonConverter in JSON.NET to deserialize a List of base class objects?](https://stackoverflow.com/q/8030538/3744182) for details. – dbc Jul 01 '22 at 21:31

1 Answers1

1

you can use Custom Json Converter if you are using system.text.json and there is an example of how you can do it

public class ComponentJsonConverter : JsonConverter<Component>
{
  public override Component Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) 
  {
    var type = JsonDocument.Parse(reader.GetRawText())
      .RootElement.GetProperty("PartType").GetString();
    if (type == "Engine")
      return JsonSerializer.DeserializeAsync<Engine>(reader.GetRawText());
    ...
  }
    
  public override void Write(Utf8JsonWriter writer, Component value, JsonSerializerOptions options) =>
    writer.WriteStringValue(JsonSerializer.Serialize(value, options));
}
Parsa S
  • 145
  • 5