1

I'm working on an ASP .NET core web api where I'm trying to create a model in C# based on a JSON that can have dynamic properties.

  1. The type field can be of 3 types: Land, Water, Air. Based on the type, the corresponding properties in the "source" would be different.

For example. if the type is "Land", there would be an additional property in source called "speed". If the type is "Air", there would be 2 additional properties in source called "Height" and "NumberLandings".

  1. The modify property is an array that can have different types of modifications - Performance/Aesthetic/Functional...., and based on the modification type, I can have different properties underneath for that modification.

For example, if the type is "Performance", there would be additional properties such as brakes/turbo/suspension.

{
    "properties": {
        "source": {
            "type": "Land",
            "speed": "160mph"
        },
        "modify ": [
            {
                "type": "Performance",
                "brakes": "",
                "turbo": "",
                "suspension": ""
            
            },
            {
                "type": "Functional",
                "electric": "",
                "applications": "Carplay"
            }

        ]
        }
    }

Question: How can I construct my C# class/model for the dynamic JSON? I'm thinking to keep the source type and modification type as an enum, and based on the enum type, define the other parameters.

I don't want to define all the properties and end up having some of them as null, like below:

    [DataContract]
    public class Source
    {
        [DataMember]
        [JsonProperty(PropertyName = "type")]
        public string Type { get; set; }

       
        [DataMember]
        [JsonProperty(PropertyName = "speed")]
        public string Speed{ get; set; }

        [DataMember]
        [JsonProperty(PropertyName = "height")]
        public string Height{ get; set; }

        [DataMember]
        [JsonProperty(PropertyName = "NumberLandings")]
        public string NumberLandings { get; set; }
    }
ProgrammingLlama
  • 36,677
  • 7
  • 67
  • 86
ach5
  • 11
  • 1
  • So the properties present directly corresponds to the type? – ProgrammingLlama Sep 30 '21 at 07:16
  • Your only other option is to write a custom JSON deserialiser that reads `properties.source.type` and based on that, reads `properties.modify` into the specific object. Then your deserialisation method will return a tuple of `(VehicleType, object)` and based on the former, you cast the latter. It's ugly, and is also the reason why APIs that return different JSON are considered poor. – Ian Kemp Sep 30 '21 at 07:22

1 Answers1

1

The type field can be of 3 types: Land, Water, Air. Based on the type, the corresponding properties in the "source" would be different.

This is essentially polymorhism, and there are existing questions and articles regarding this. This might require a custom jsonConverter class, and it might be easier if you format your message to have a separate object, rather than loose properties, i.e:

"type": "Land",
 "MyBaseObject":{           
      "speed": "160mph"
  }

The modify property is an array that can have different types of modifications - Performance/Aesthetic/Functional...., and based on the modification type, I can have different properties underneath for that modification.

This sounds like a key-value store, and may use the same approach to polymorphism as above to store different properties for different kinds of objects, i.e. it could be represented by a Dictionary<string, MyModificationBase>.

Keep in mind that you still need to use the object model somehow, preferably without needing do typechecking all over the place.

JonasH
  • 28,608
  • 2
  • 10
  • 23