【问题标题】:Change Value in JSON更改 JSON 中的值
【发布时间】:2016-11-10 18:13:49
【问题描述】:

我有以下 JSON:

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

点击我想改变音量,我尝试用这个 sn-p 来做:

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

现在最后一行抛出

使用无效键值访问的 JArray 值:“192.168.10.214”。需要 Int32 数组索引。

如何更新指定 IP 的卷?我是using Newtonsoft.Json;

任何提示表示赞赏!

编辑

按要求提供完整功能:

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

【问题讨论】:

  • 能否不反序列化为一个对象并为IP更改Volume的属性值?

标签: c# json json.net


【解决方案1】:

"Sonos" 是一个数组,子项及其值也是一个数组。

所以访问如下:

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

编辑:

对于foreach 迭代,考虑类似的事情(hacky 但如果结构得到保证,那么这应该可以工作耸耸肩):

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

理想情况下,您应该将Sonos 更改为以地址值作为键的 JSON 字典。

【讨论】:

  • 这改变了第一次的音量,但在第二次迭代中抛出了Null-Pointer Exception
  • 会的。我进行了编辑以展示如何解决迭代问题。
  • 我相信jsonObj["Sonos"][index][address[index]][0]["Volume"] = "10"; 应该是jsonObj["Sonos"][index][address[0]][index]["Volume"] = "10"; ,但这也不起作用,这里是完整的功能pastebin.com/ciqs5DGq
  • 目前无法查看 pastebin - 最好编辑您的问题并包含整个代码。
  • 您将始终使用address[0] 引用第一个地址项。这是你想要的吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-27
相关资源
最近更新 更多