【问题标题】:C# Getting number of items in a JSON array that is in another JSON ObjectC#获取另一个JSON对象中的JSON数组中的项目数
【发布时间】:2019-10-03 08:52:56
【问题描述】:

我正在尝试获取数组“channels”中的项目数,该数组位于名为“modes”的数组中。我已经很容易从“modes”数组中的正确项中获取名称,但现在我需要获取“channels”数组中的项数。

“modes”数组中的每个“name”都在一个名为“cbxModes”的组合框中。我试过有一个if语句说“name”等于“cbxModes.SelectedItem”,然后从“modes”中的这个项目获取“channels”中的项目数

这是我的 JSON

"modes": [
{
  "name": "1 – Standard 16bit RGBW",
  "shortName": "1-16bitRGBW",
  "channels": [
    "Pan",
    "Pan fine",
    "Tilt",
    "Tilt fine",
    "Pan/Tilt Speed",
    "Special Functions",
    "Virtual Color Wheel",
    "Red",
    "Red fine",
    "Green",
    "Green fine",
    "Blue",
    "Blue fine",
    "White",
    "White fine",
    "CTC",
    "Color Mix Control",
    "Zoom",
    "Zoom fine",
    "Shutter / Strobe",
    "Dimmer",
    "Dimmer fine"
  ]
},
{
  "name": "2 – Reduced 8bit RGBW",
  "shortName": "2-8bitRGBW",
  "channels": [
    "Pan",
    "Pan fine",
    "Tilt",
    "Tilt fine",
    "Pan/Tilt Speed",
    "Special Functions",
    "Virtual Color Wheel",
    "Red",
    "Green",
    "Blue",
    "White",
    "CTC",
    "Color Mix Control",
    "Zoom",
    "Dimmer"
  ]
},
{
  "name": "1 – Standard 16bit CMY",
  "shortName": "1-16bitCMY",
  "channels": [
    "Pan",
    "Pan fine",
    "Tilt",
    "Tilt fine",
    "Pan/Tilt Speed",
    "Special Functions",
    "Virtual Color Wheel",
    "Cyan",
    "Cyan fine",
    "Magenta",
    "Magenta fine",
    "Yellow",
    "Yellow fine",
    null,
    null,
    "CTC",
    "Color Mix Control",
    "Zoom",
    "Zoom fine",
    "Shutter / Strobe",
    "Dimmer",
    "Dimmer fine"
  ]
},
{
  "name": "2 – Reduced 8bit CMY",
  "shortName": "2-8bitCMY",
  "channels": [
    "Pan",
    "Pan fine",
    "Tilt",
    "Tilt fine",
    "Pan/Tilt Speed",
    "Special Functions",
    "Virtual Color Wheel",
    "Cyan",
    "Magenta",
    "Yellow",
    null,
    "CTC",
    "Color Mix Control",
    "Zoom",
    "Shutter / Strobe",
    "Dimmer"
  ]
}
],

这是我的 C#

private void CbxMode_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        string FixtureRoot = AppDomain.CurrentDomain.BaseDirectory + "Fixtures\\" + cbxManufacture.SelectedItem + "\\";

        string ModeRoot = null;

        var JSON_Mode_Count = (JObject)null;

        for (int i = 0; i < Directory.GetFiles(FixtureRoot).Length; i++)
        {
            var Fixtures = Directory.GetFiles(FixtureRoot);
            string Names = File.ReadAllText(Fixtures[i]);
            var JSON_Name = JsonConvert.DeserializeObject<dynamic>(Names);
            if (JSON_Name.name == cbxFixture.SelectedItem)
            {
                ModeRoot = AppDomain.CurrentDomain.BaseDirectory + "Fixtures\\" + cbxManufacture.SelectedItem + "\\" + JSON_Name.fixtureKey.ToString() + ".json";
                JSON_Mode_Count = JObject.Parse(File.ReadAllText(ModeRoot));

                JArray Modes = (JArray)JSON_Mode_Count["modes"];
                int numberOfModes = Modes.Count;

                string ModesJSON = File.ReadAllText(ModeRoot);
                var JSON_Mode = JsonConvert.DeserializeObject<dynamic>(ModesJSON);

                foreach (var obj in JSON_Mode.modes)
                {
                    foreach (var obj2 in obj.channels)
                    {
                        if (obj.name == cbxMode.SelectedItem)
                        {
                            JArray Channels = (JArray)JSON_Mode_Count["channels"];
                            int numberOfChannels = Channels.Count;

                            lblChannels.Content = numberOfChannels.ToString();
                        }
                    }

                }
            }
        }
    }

TIA

【问题讨论】:

  • 如果在 C# 中有一个 JSON 模型,您可以将 JSON 反序列化到该模型,这将更容易理解(并且您可以开发)
  • 这个问题应该使用适当的对象和反序列化自行解决。
  • 太棒了。谢谢。介意扩展您的意思吗?
  • 好的。 1.复制你的Json。 2. 在 Visual Studio 上,创建一个新类。 3.在编辑菜单中点击特殊过去“过去的json作为类”。 4.使用JsonConvert.DeserializeObject&lt;RootObject&gt;(json);现在你应该有一个真实的对象导航会更容易。拥有真实对象意味着您将轻松浏览该属性
  • 完成后,您将更清楚地了解您接下来遇到的问题。因为在动态类型对象上,我要求一个不存在的任何类型的属性,并且不知道它不是真实的。这不会解决您的问题,它会帮助您找到问题所在

标签: c# arrays json


【解决方案1】:

尝试将 json 直接映射到与 json 有直接对应关系的 c# 对象。而不是 JsonConvert.DeserializeObject&lt;dynamic&gt; 做类似 JsonConvert.DeserializeObject&lt;ModesList&gt; 的事情,你的代码会更简单。

public class ModesList
{
    [JsonProperty("modes")]
    public List<Mode> Modes { get; set; }
}

public class Mode
{
    [JsonProperty("name")]

    public string Name { get; set; }

    [JsonProperty("shortName")]

    public string ShortName { get; set; }

    [JsonProperty("channels")]
    public List<string> Channels { get; set; }
}

【讨论】:

  • 那我想我必须创建一个“ModesList”类?
  • @HarryBilney,视觉工作室特别过去或json2csharp.com。 Json是对象的序列化,因此基于json创建对象的定义很容易。
【解决方案2】:

将 json 的具体模型创建为 C# 类通常更容易。您可以在以下类上创建 json 模型(使用 json2csharp.com 之类的东西或特殊粘贴到 Visual Studio 中):

public class Mode
{
    public string Name { get; set; }
    public string ShortName { get; set; }
    public List<string> Channels { get; set; }
}

public class RootObject
{
    public List<Mode> Modes { get; set; }
}

然后你可以反序列化使用:

var data = JsonConvert.DeserializeObject<RootObject>(json);
foreach (var mode in data.Modes)
{
    var channels = mode.Channels;
    var channelCount = channels.Count();

    Console.WriteLine($"Name: {mode.Name}, Name: {mode.ShortName}, ChannelCount: {channelCount}"); 
}

【讨论】:

    【解决方案3】:

    网上有一些工具可用于从 C# 代码自动生成类,但我不喜欢它们,更喜欢手动方式,因此我将展示并尝试解释该过程。

    JSON 是结构化的,JSON 中的一切都是具有属性的对象。这是一个非常简单的例子:

    {
        "Name": "John",
        "Surname": "Doe"
    }
    

    这是一个有效的 JSON,它表示具有两个属性 NameSurname 的对象,C# 表示是这样的:

    public class Person
    {
        public string Name {get; set;}
        public string Surname {get; set;}
    }
    

    使用 Newtonsoft,我们现在可以将我们的 JSON 反序列化为这个对象,如下所示:

    JsonConvert.DeserializeObject<Person>(json);
    

    这是最简单的 JSON 反序列化形式,我们没有嵌套对象,也没有列表/数组。现在让我们看看那些:

    {
        "Name": "John",
        "Surname": "Doe",
        "Children": [{
                "Name": "Jane",
                "Surname": "Doe"
            },
            {
                "Name": "Jack",
                "Surname": "Doe"
            }
        ]
    }
    

    这现在包含一个 JSON 数组 ([ ... ]) 的对象。我们可以看到这些对象再次只是人。所以我们可以把我们的 person 类改成这样:

    public class Person
    {
        public string Name {get; set;}
        public string Surname {get; set;}
        public List<Person> Children {get; set;}
    }
    

    现在让我们来看看您的实际 JSON。看看这是我想出的数据结构:

    public class Parent
    {
        [JsonProperty("modes")]
        public List<Mode> Modes {get; set;}
    }
    
    public class Mode
    {
        public string Name {get; set;}
        public string ShortName {get; set;}
        public List<string> Channels {get; set;}
    }
    

    您现在可以像这样反序列化 JSON:

    var deserialized = JsonConvert.DeserializeObject<Parent>(json);
    

    我希望这对您未来的项目有所帮助。

    编辑:这不会完全起作用。我在 JSON 的开头没有看到 "modes": [,这意味着有一个我一无所知的 Parent 对象。我修复了反序列化

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-28
      • 2020-06-08
      • 1970-01-01
      • 2021-08-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多