【问题标题】:How to fetch the key in nested JSON File and add it to a Combo Box如何获取嵌套 JSON 文件中的密钥并将其添加到组合框
【发布时间】:2018-10-10 07:12:59
【问题描述】:

我想从嵌套的 JSON 文件中读取属性名称并将其更新为 Windows 表单中的组合框。这就是我的 JSON 文件的嵌套方式,

{
   "Configurations": {
      "Tr984": {
         "Operations": {
            "pressure": {
               "speed": 1000,
               "IpAddress": "*****",
               "TcpPort": ***,
               "UnitId": ****,
               and so on..
            },
            "Engage":{
               "Interval": 1000,
               "IpAddress": "****",
               "TcpPort": ***,
               "UnitId": ****,
               and so on..
            },
            "Volume": {
               "density": 1000,
               "IpAddress": "****",
               "Port": 8888,
               "
            }
         }
      }
   }

我想访问所有键名Pressure,Engage,Volume 并将其添加到comboBox1,动态地。目前我正在使用每个循环来到达最里面的键、值对和无法仅获取上述属性。由于我是 C# 编码的初学者,您能帮我解决这个问题吗?

private void comboBox1_Click(object sender,EventArgs e)
{
    using (StreamReader r = new StreamReader(@"**********"))
    {
        var json = r.ReadToEnd();
        var jobj = JObject.Parse(json);

        foreach (var item in jobj.Properties())

            foreach (var item2 in item.Value)

                foreach (var item3 in item2)

                    foreach (var item4 in item3)

                        foreach (var rawTags in item4)

                            foreach (var pair in rawTags)

                                foreach (var value in pair)
                                {
                                    string propName=Convert.ToString(value.Next);
                                    comboBox1.Items.Add(propName);  
                                }
    }
} 

【问题讨论】:

  • 递归方法怎么样?
  • 我知道使用很多这样的 foreach 循环不是一个好习惯,所以您能否建议如何获取上述属性名称?

标签: c# json winforms combobox


【解决方案1】:

最简单的方法是围绕您的 json 建模一个类并将其直接反序列化到该类中。
为了围绕你的 json 建模一个类,你可以使用像 json2csharp 这样的工具。这将为您提供此类结构:

public class Pressure
{
    public int speed { get; set; }
    public string IpAddress { get; set; }
    public int TcpPort { get; set; }
    public int UnitId { get; set; }
}

public class Engage
{
    public int Interval { get; set; }
    public string IpAddress { get; set; }
    public int TcpPort { get; set; }
    public int UnitId { get; set; }
}

public class Volume
{
    public int density { get; set; }
    public string IpAddress { get; set; }
    public int Port { get; set; }
}

public class Operations
{
    public Pressure pressure { get; set; }
    public Engage Engage { get; set; }
    public Volume Volume { get; set; }
}

public class Tr984
{
    public Operations Operations { get; set; }
}

public class Configurations
{
    public Tr984 Tr984 { get; set; }
}

public class RootObject
{
    public Configurations Configurations { get; set; }
}

现在你可以使用像Json.Net 这样的框架来反序列化给定的json:

var obj = JsonConvert.DeserializeObject<RootObject>(json);

然后像这样访问密钥:

var pressure = obj.Operations.pressure
// and so on

如果您的 json 字符串太大而无法围绕它建模一个类,您可以使用 Json.Net dynamic features:

dynamic configurations = JArray.Parse(json);
dynamic pressure = configurations.Tr984.Operations.pressure;
var speed = pressure.speed;
// and so on

更新
如果您在编译时不知道 json 结构,并且只想要 Operations 节点之外的键名,您可以从上面修改我的示例来实现这一点。

更改类结构,以便将 Operations 的所有子代而不是特定键反序列化为字典:

public class Tr984
{
    public Dictionary<string,object> Operations { get; set; }
}

public class Configurations
{
    public Tr984 Tr984 { get; set; }
}

public class RootObject
{
    public Configurations Configurations { get; set; }
}

现在反序列化后:

var obj = JsonConvert.DeserializeObject<RootObject>(json);

每个 json 键都将是字典中的一个键。要让它们简单地迭代它们:

foreach(var key in obj.Configurations.Tr984.Operations.Keys)
{
    comboBox1.Items.Add(key);
}

【讨论】:

  • 感谢您的回答我会尝试我的问题是在 JSON 文件中进行更改时添加了更多属性值对,如压力或参与或音量,这些键名(如压力,音量) 应该在表单的组合框中自动更新。所以我需要一个建议来自动将压力、音量等键名和任何其他键名添加到 JSON 文件中,这样就无需修改代码,因为它会自动更新添加的组合框的键名。请有人帮忙
【解决方案2】:

您可以通过以下方式访问它:

dynamic obj = JsonConvert.DeserializeObject(json);

var pressure = obj.Configurations.Tr984.Operations.pressure;

【讨论】:

    【解决方案3】:

    这里你需要查询你的JObjectlike

    JObject jObject = JObject.Parse(json);
    
    var result = jObject["Configurations"]["Tr984"]["Operations"].Children().Children().ToList().Select(x => x.ToObject<JObject>()).Properties().Select(y => new { Key = y.Name, Value = y.Value });
    
    foreach (var i in result)
    {
        //comboBox1.Items.Add(i.Value);  
        Console.WriteLine(i.Key + ": " + i.Value);
    }
    
    Console.ReadLine();
    

    为了您的理解目的,或者更简化的方式。

    JObject jObject = JObject.Parse(json);
    
    var result = jObject["Configurations"]["Tr984"]["Operations"].Children().Children().ToList();
    
    foreach (JToken token in result)
    {
        JObject jObject1 = token.ToObject<JObject>();
    
        foreach (JProperty property in jObject1.Properties())
        {
            //comboBox1.Items.Add(property.Value);  
            Console.WriteLine(property.Name + ": " + property.Value);
        }
    }
    
    Console.ReadLine();
    

    输出:

    【讨论】:

    • @pooja,如果回答对您有帮助,请在回答左侧打勾,使其变为绿色:)
    猜你喜欢
    • 1970-01-01
    • 2022-01-10
    • 1970-01-01
    • 2019-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多