Search code examples
c#jsonjson.netjson-deserializationgeneric-list

Deserialize a json object with multiple nested objects /lists using JsonConvert


I a beginner in C# application development and have the following json data which I want to de-serialize:

{
    "Parameters": [
        {
            "Info": {
                "Id": 0,
                "No": "0001"
            },
            "IntOptions": [
                {
                    "Value": 0,
                    "ValInfo": "FIFO"
                },
                {
                    "Value": 1,
                    "ValInfo": "FIFO2"
                }
            ],
            "BubbleList": [
                {
                    "Position": 0,
                    "SubBubbleList": [
                        {
                            "Value": 0,
                            "Message": "ListObj1"
                        },
                        {
                            "Value": 1,
                            "Message": "ListObj2"
                        }
                    ]
                }
            ]
        }
    ]
}

I have the class structure defined as follows:

public class ParamList
  {
    private List<Param> _param = new List<Param>();

    [JsonProperty("Parameters")]
    public IReadOnlyCollection<Param> Param { get => _param.AsReadOnly(); } 
  }

public class Param
{
    private List<IntOptions> _intOptions;
    private List<BubbleList> _bubbleList;

    [JsonProperty("Info")]
    public Info? Info { get; }

    [JsonProperty("IntOptions")]
    public IReadOnlyCollection<IntOptions> IntOptionsVar { get => _intOptions.AsReadOnly(); }

    [JsonProperty("BubbleList")]
    public IReadOnlyCollection<BubbleList> BubbleListVar { get => _bubbleList.AsReadOnly(); }
}

public class Info
{
    public Info(int id, string number)
    {
      Id = id;
      Number = number;
    }

    [JsonProperty("Id")]
    public int Id { get; private set; }

    [JsonProperty("No")]
    public string Number { get; private set; }
}

public class IntOptions
{
    public IntOptions(int value, string valInfo)
    {
      Value = value;
      ValInfo = valInfo;
    }

    [JsonProperty("Value")]
    public int Value { get; private set; }

    [JsonProperty("ValInfo")]
    public string ValInfo { get; private set; }
}

public class BubbleList
{
    private List<SubBubbleList>? _subBubbleList;

    public BubbleList(int position)
    {
      Position = position;
    }

    [JsonProperty("Position")]
    public int Position { get; private set; }

    [JsonProperty("SubBubbleList")]
    public IReadOnlyCollection<SubBubbleList> SubBubbleListVar { get => _subBubbleList.AsReadOnly(); }
}

public class SubBubbleList
{
    public SubBubbleList(int value, string message)
    {
      Value = value;
      Message = message;
    }

    [JsonProperty("Value")]
    public int Value { get; private set; }

    [JsonProperty("Message")]
    public string Message { get; private set; }
}

I came up with the following de-serializing code which results in an empty list of Param:

 try
    {
      ParamList paramList = JsonConvert.DeserializeObject<ParamList>(readJsonContent);
      Console.WriteLine(paramList);
    }

This gives me an empty list of Param.

I read a lot of articles explaining about de-serializing a json object, however, could not find one which would solve my use case. I need to understand what am I doing wrong here. I need to have a List<Param> which would then have Info, List<IntOptions>, & List<BubbleList> -> List<SubBubbleList>.

Is this achievable by just de-serializing the json data, or will I have to iterate through individual objects?


Solution

  • you have only getters in your classes. you need setters to assign values from json to c# objects

    List<Parameter> Parameters = JsonConvert.DeserializeObject<ParamList>(json).Parameters;
    

    classes

    public class ParamList
    {
        public List<Parameter> Parameters { get; set; }
    }
    
    public class Parameter
    {
        public Info Info { get; set; }
        public List<IntOption> IntOptions { get; set; }
        public List<BubbleList> BubbleList { get; set; }
    }
    
    public class BubbleList
    {
        public int Position { get; set; }
        public List<SubBubbleList> SubBubbleList { get; set; }
    }
    
    public class Info
    {
        public int Id { get; set; }
        public string No { get; set; }
    }
    
    public class IntOption
    {
        public int Value { get; set; }
        public string ValInfo { get; set; }
    }
    
    public class SubBubbleList
    {
        public int Value { get; set; }
        public string Message { get; set; }
    }
    

    but if for some reasons you still need readonly you can change ALL your read only classes by moving json property name using this template

    public class ParamList
    {
        [JsonProperty("Parameters")]
        private List<Param> _param = new List<Param>();
    
        public IReadOnlyCollection<Param> Param
        {
            get => _param.AsReadOnly();
        }
    }