PrimuS PrimuS - 1 month ago 22
C# Question

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++;
}
}

Answer

"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.