0

An object within a product that I am working with has a list of 'Features' that have at least one common property across the board i.e 'name', but then the properties can wildly vary. One option that is simple and works is to put all the possibilities in to a Feature class and allow the property to be null if it doesn't have a value, but this doesn't seem to be the right approach, as the result in console is a lot of empty properties when it is deserialised. What I would like to do is have a base 'Feature' class and then derived classes for each individual feature, but I am not sure how to deserialise it or if this is possible. I looked at Conditional Property Serialisation, but it doesn't appear to be what I am after.

Here's an example of the Json and classes that I would like to deserialise, and have the ability to serialise once more. I would appreciate any input anyone can offer on this.

JSON

"features": [{
    "name": "dhcp",
    "enabled": true,
    "version": 1,
    "ipPool": "192.168.0.1-192.168.1.254"
}, {
    "name": "interface",
    "enabled": true,
    "ifName": "Test",
    "ifType": "physical",
    "ipAddress": "10.0.0.1"
}, {
    "name": "firewall",
    "version": 10,
    "rules": [{
        "source": "Dave's-PC",
        "destination": "any",
        "port": 80,
        "allow": false
    }, {
        "source": "Dave's-PC",
        "destination": "all-internal",
        "port": 25,
        "allow": true
    }]
}]

Classes

namespace Test 
{
    public class Features
    {
        [JsonProperty("features", NullValueHandling = NullValueHandling.Ignore)]
        public List<Feature> FeatureList { get; set; }
    }

    public abstract class Feature 
    {
        [JsonProperty("name")]
        public string Name { get; set; }

        [JsonProperty("version", NullValueHandling = NullValueHandling.Ignore)]
        public long? Version { get; set; }

        [JsonProperty("enabled", NullValueHandling = NullValueHandling.Ignore)]
        public bool? Enabled { get; set; }
    }

    public class Dhcp : Feature
    {
        [JsonProperty("ipPool")]
        public string IPPool { get; set; }
    }

    public class Interface : Feature
    {
        [JsonProperty("ifName")]
        public string InterfaceName { get; set; }

        [JsonProperty("ifType")]
        [JsonConverter(typeof(InterfaceTypeConverter))]     // I have an enum and converter class elsewhere for this.
        public InterfaceType InterfaceType { get; set; }

        [JsonProperty("ipAddress")]
        [JsonConverter(typeof(IPAddressConverter))]     // I have an enum and converter class elsewhere for this.
        public IPAddress IP { get; set; }
    }

    public class Firewall : Feature
    {
        [JsonProperty("rules", NullValueHandling = NullValueHandling.Ignore)]
        public List<Rule> Rules {get; set; }
    }

    public class Rule
    {
        [JsonProperty("source")]
        public string Source { get; set; }

        [JsonProperty("destination")]
        public string Destination { get; set; }

        [JsonProperty("port")]
        public long Port { get; set; }

        [JsonProperty("allow")]
        public bool Allowed { get; set; }
    }
}

The end goal would be I only need to deserialise what is there for each feature in the object, and, if I wanted to create a new feature, I would have a derived class that just contains what that feature needs to add to List<Feature>. Apologies if I've missed an explanation of this somewhere else, I have searched all afternoon, but I've either found information on ignoring null properties or I don't understand what is being said. I believe that I may need a custom converter class and possibly some way of identifying the name value for each 'Feature', but I am not sure where to start. Thanks for any help.

Ash
  • 3,030
  • 3
  • 15
  • 33
  • 2
    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). – dbc Apr 15 '20 at 17:31
  • 2
    Thanks for pointing me in the right direction. I wasn't quite sure what I was looking for as far as searching for the correct term. I've managed to write a working solution from various components in the links you sent. Thanks again. – Ash Apr 16 '20 at 15:29

1 Answers1

1

You'll have to write a custom converter to handle that. Here's a similar question which covers your use-case, I believe.

Joelius
  • 3,839
  • 1
  • 16
  • 36