PrimuS
PrimuS

Reputation: 2683

Change Value in JSON

I have the following JSON:

{
"Sonos": [
    {
      "192.168.10.214": [
        {
          "Volume": "5",
          "Extension": null,
          "Name": "Wohnzimmer"
        }
      ]
    },
    {
      "192.168.10.204": [
        {
          "Volume": "5",
          "Extension": null,
          "Name": "Büro"
        }
      ]
    }
  ]
}

On click I want to change the Volume, I try to do it with this snippet:

string[] address = ip.Text.Split(new string[] {" | "}, 
    StringSplitOptions.RemoveEmptyEntries); //ip is a ListViewItem
...
dynamic jsonObj = JsonConvert.DeserializeObject(config);
jsonObj["Sonos"][address[0]]["Volume"] = "10";

Now the last line throws

Accessed JArray values with invalid key value: "192.168.10.214". Int32 array index expected.

How would I update the Volume for the specified IP? I am using Newtonsoft.Json;

Any hint appreciated!

EDIT

Full function as per request:

private void IncomingCall()
        {
            int i = 0;
            foreach (ListViewItem ip in sonosListExt1.Items)
            {
                string[] address = ip.Text.Split(new string[] {" | "}, StringSplitOptions.RemoveEmptyEntries);

                /* Get current Volume and save */
                string getVol = sendXML("/MediaRenderer/RenderingControl/Control", "GetVolume",
                    "urn:schemas-upnp-org:service:RenderingControl:1",
                    "<InstanceID>0</InstanceID><Channel>Master</Channel>", address[0]);

                XmlDocument xmlResponse = new XmlDocument();
                xmlResponse.LoadXml(getVol);
                var curVol = ((XmlElement) xmlResponse.FirstChild.FirstChild.FirstChild).InnerText;

                string config = File.ReadAllText(AppDomain.CurrentDomain.BaseDirectory + "cfg\\config.json");
                dynamic jsonObj = JsonConvert.DeserializeObject(config);
                jsonObj["Sonos"][i][address[0]][i]["Volume"] = curVol;
                string output = JsonConvert.SerializeObject(jsonObj, Newtonsoft.Json.Formatting.Indented);
                File.WriteAllText(AppDomain.CurrentDomain.BaseDirectory + "cfg\\config.json", output);

                /* Lower Volume */
                sendXML("/MediaRenderer/RenderingControl/Control", "SetVolume",
                    "urn:schemas-upnp-org:service:RenderingControl:1",
                    "<InstanceID>0</InstanceID><Channel>Master</Channel><DesiredVolume>2</DesiredVolume>", address[0]);

                /* Var up */
                i++;
            }
        }

Upvotes: 0

Views: 455

Answers (1)

toadflakz
toadflakz

Reputation: 7934

"Sonos" is an array as are the subitems and their values.

So access as follows:

jsonObj["Sonos"][0][address[0]][0]["Volume"] = "10";

Edit:

For the foreach iteration, consider something similar to this (hacky but if the structure is guaranteed then this should work shrug):

foreach (ListViewItem ip in sonosListExt1.Items)
{
    var index = sonosListExt1.Items.ToList().IndexOf(ip);
    string[] address = ip.Text.Split(new string[] {" | "}, StringSplitOptions.RemoveEmptyEntries);

   /* --- Excluded XML manipulation code --- */

   jsonObj["Sonos"][index][address[0]][0]["Volume"] = "10";  
}

Ideally you should change Sonos to be a JSON Dictionary with the address values as the key.

Upvotes: 2

Related Questions