0

Let's say I wish to create a diary to keep track an infant's daily activities.

I have a parent class called DiaryEntries (fields: DateTime, PerformBy)

Then I have 2 sub-class called: FeedingEntries (fields: FoodType, Volume) DiaperingEntries (fields: PeePoop, DiaperBrand)

The records is saved in a JSON file. Sample:

{
  "entries": [
    {
      "DateTime": "2020-11-02T21:38:53.4372208+08:00",
      "PerformBy": "Jane",
      "PeePoop": "Pee",
      "DiaperBrand": "Pampers"
    },
    {
      "DateTime": "2020-11-02T21:38:53.4379914+08:00",
      "PerformBy": "Andy",
      "FoodType": "Milk",
      "Volume": "120ml"
    },
    {
      "DateTime": "2020-11-02T21:38:53.438086+08:00",
      "PerformBy": "Andy",
      "PeePoop": "Poop",
      "DiaperBrand": "Diaper"
    }
  ]
}

How do I map this JSON to the 3 objects when I wish to return a list of DiaryEntries and its sub-class?

If I map the JSON to DiaryEntries object, then I only get DateTime and PerformBy. I tried to create another object which has all the fields but I think that this is wrong as I will have to add more fields to this object next time I have another entry type.

stand
  • 1
  • Do you have control of how it is serialized? If so, this may work: https://stackoverflow.com/a/42858968/5803406 – devNull Nov 10 '20 at 02:20
  • How are you de-serializing the json string? I think your tag of inheritence holds the key. De-serialize into a relatively abstract class(e.g. BabyActivity) and then use a hook in the deserialization process to cast and assign to the proper sub class(e.g. PeePooBabyActivity or FeedBabyActivity). – Adam Nov 10 '20 at 02:24
  • 1
    If you're using System.Text.Json, then this will help: https://stackoverflow.com/a/59744873/5803406 – devNull Nov 10 '20 at 02:25

2 Answers2

0

I'm not aware of any way to automatically deserialize into different subclasses based on properties found. Instead though why not make your properties more generic like this:

{   
"entries": [
{
  "DateTime": "2020-11-02T21:38:53.4372208+08:00",
  "PerformBy": "Jane",
  "Activity": "Pee",
  "Details": "Pampers"
},
{
  "DateTime": "2020-11-02T21:38:53.4379914+08:00",
  "PerformBy": "Andy",
  "Activity": "Milk",
  "Details": "120ml"
},
{
  "DateTime": "2020-11-02T21:38:53.438086+08:00",
  "PerformBy": "Andy",
  "Activity": "Poop",
  "Details": "Diaper"
}   
] }

Then you really only need one class with DateTime, PerformBy, Activity and Details properties. Activity & Details could be enums to programmatically distinguish them if needed.

Michael Tucker
  • 205
  • 2
  • 10
0

As per your description following Jason is valid and I am assuming subclasses will be list.

{
"entries": [
{
  "DateTime": "2020-11-02T21:38:53.4372208+08:00",
  "PerformBy": "Jane",
  "DiaperingEntries ":[{
      "PeePoop": "Pee",
      "DiaperBrand": "Pampers"
  }]
},
{
  "DateTime": "2020-11-02T21:38:53.4379914+08:00",
  "PerformBy": "Andy",
  "FeedingEntries":[{
       "FoodType": "Milk",
      "Volume": "120ml"
  }]    
},
{
  "DateTime": "2020-11-02T21:38:53.438086+08:00",
  "PerformBy": "Andy",
   "DiaperingEntries ":[{
      "PeePoop": "Poop",
      "DiaperBrand": "Diaper"
  }]
}
]
}

And you could deserialize everything as base object and cast it as per your want.

anand shukla
  • 666
  • 5
  • 14