Search code examples
c#jsonobject

How can I access my nested data using variables C#


I have a json file and I deserialised it as shown in the code below. Some context, dex is a robot and it has information such as battery and so on as shown in the json file below. I want to read the battery status for the robot that the user selected ( robot).

This is my code, currently im only accessing data.dex but i want to change it to whichever data.robot, where robot is a variable

            var data = JsonConvert.DeserializeObject<Root>(json);
            var robot = queryDetails2.Amr;
            var text =$"";
            if (data.dex.battery.status == "good")
            {
                text = $"{queryDetails2.Amr}'s battery is in good condition. ";
            }

This is the json file:

{
    "dex":
    {
    "current_job":
        {"job":null, "task": null, "location": null},
    "battery": 
        {"name":"battery", "status": "good", "value": "100"},
    },

    "dex_1":
    {
    "current_job":
        {"job":null, "task": null, "location": null},
    "battery": 
        {"name":"battery", "status": "good", "value": "100"},
    },

    "dex_2":
    {
    "current_job":
        {"job":null, "task": null, "location": null},
    "battery": 
        {"name":"battery", "status": "good", "value": "100"},
    }
}    

I wanted to use the GetMethod or the solution as suggested in this question (https://stackoverflow.com/questions/53076743/how-to-access-variable-of-a-nested-functions-in-python[1]).

However, im getting errors like it does not have a method. Now im confused, was it because i used var? but the deserialised method converts the json to an object though..

Anyway, how should i approach this?


Solution

  • Assuming that you have 3 robots with different names: dex, dex_1 and dex_2, you should reorganize your solution to treat the json data as a list of Robots instead of 3 separate variables for each robot.

    To do this, first your json should look like this:

    {
       "robots":[
       {
          "name":"dex",
          "current_job":{
             "job":null,
             "task":null,
             "location":null
          },
          "battery":{
             "name":"battery",
             "status":"good",
             "value":"100"
          }
       },
       {
          "name":"dex_1",
          "current_job":{
             "job":null,
             "task":null,
             "location":null
          },
          "battery":{
             "name":"battery",
             "status":"good",
             "value":"100"
          }
       },
       {
          "name":"dex_2",
          "current_job":{
             "job":null,
             "task":null,
             "location":null
          },
          "battery":{
             "name":"battery",
             "status":"good",
             "value":"100"
          }
       }]
    }
    

    Next, update your serialization classes. Add a field called name in the Robot class or whatever class type you currently have for data.dex. In Root, remove the "dex" fields and add a List<Robot>.

    public class Root
    {
        public List<Robot> robots { get; set; }
    }
    
    
    public class Robot
    {
        public string name { get; set; }
        public Job current_job { get; set;}
        public Battery battery{ get; set; }
    }
    

    Now you can write whatever logic to get the right robot data. Here is an example using System.Linq:

    var robotName = "dex_2";
    var robotInfo = data.robots.First(x => x.name.Equals(robotName));
    var text = $"{robotName}'s battery is in {robotInfo.battery.status} condition.";