【问题标题】:dynamically converting a JSON structure to an array将 JSON 结构动态转换为数组
【发布时间】:2019-02-27 00:35:13
【问题描述】:

在我的 C# 代码中,我调用了一个端点,该端点将类似于此的结构发回

{       
       "name":"test",
        "clients": {
            "client1": {"id": "1", "count": "41"},
            "client2": {"name": "testName"},
            "client3": {"CustomerID": "a1", "internalID": "testID"}
        }
}

我需要将其转换为 C# 对象,然后遍历“客户端”。问题是事先我不知道客户端名称(在上面的示例中为“client1”、“client2”和“client3”)或可以返回的客户端数量。

所以在我的代码中,我有以下 C# 文件

public class result
{

        public string name { get; set; }

        [JsonProperty("clients")]
        public string[] clients { get; set; }
}

但是,当我尝试使用 JsonConvert.DeserializeObject 解析它时,我得到一个错误。理想情况下,我想做的是将客户端转换为 C# 数组,然后遍历它们。

【问题讨论】:

  • 您的 JSON 示例不是有效的 JSON。我了解您正在尝试说明一个概念,但为了帮助您解析实际字符串,我们需要以您必须使用的格式查看实际字符串。您能否模拟 JSON 示例中的元素以使其具有适当的代表性?
  • 谢谢,我更新了一个有效的 JSON。请注意,我不需要遍历每个客户端的属性,我只需要自己获取客户端名称,如上例中的“client1”、“client2”和“client3”

标签: c# json


【解决方案1】:

我会用...

public class result
{

    public string name { get; set; }

    [JsonProperty("clients")]
    public Dictionary<string, dynamic> Clients { get; set; }
}

用代码...

result test = JsonConvert.DeserializeObject<result>(Resource1.JSON);

Console.WriteLine(test.Clients["client1"].id);
Console.WriteLine(test.Clients["client2"].name);
Console.ReadLine();

输出...

1 
testName

或者,如果您不确定属性,您可以按如下方式进行调整

public class result
{

    public string name { get; set; }

    [JsonProperty("clients")]
    public Dictionary<string, ExpandoObject> Clients { get; set; }
}

用代码...

result  test = JsonConvert.DeserializeObject<result>(Resource1.JSON);

foreach(string key in test.Clients.Keys)
{
    ExpandoObject obj = test.Clients[key];
    var dict = obj as IDictionary<string, object>;
    dynamic client = obj;
    if (dict.ContainsKey("id"))
        Console.WriteLine(client.id);

    if (dict.ContainsKey("name"))
        Console.WriteLine(client.name);
}

产生相同的输出

【讨论】:

  • 感谢大家的cmets。几乎所有这些都有效,我决定继续使用 ExpandoObject。
【解决方案2】:

您需要使用 Newtonsoft.JSON 包。

        var respStr = @"{
                        name:'test',
                        clients: {
                            'client1': 'Bill',
                            'client2': 'Steve',
                            'client3': 'Ryan'
                            }
                        }";
        var jsonObject = JObject.Parse(respStr);
        foreach (var item in jsonObject)
        {
            var name = item.Key;
            JToken token = item.Value;
            if (token is JObject)
            {
                foreach (var clientToken in token)
                {
                    if (clientToken is JProperty)
                    {
                        var clientStr = (clientToken as JProperty).Value;
                    }
                }
            }
            if (token is JValue)
            {
                var value = token.Value<string>();
            }
        }

【讨论】:

    【解决方案3】:

    您可以将客户端声明为对象数组以实现此目的。

    public class result
    {
    
        public string name { get; set; }
    
        [JsonProperty("clients")]
        public object[] clients { get; set; }
     }
    

    为了获取客户端名称,您可以循环访问对象数组属性名称。您可以参考下面的链接来实现这一点。

    Get properties and values from unknown object

    【讨论】:

      【解决方案4】:

      看起来客户端列表实际上是一个键控集合,也就是字典。所以你可以这样表示:

      public class Foo
      {
          public string name;
          public Dictionary<string, object> clients;
      }
      

      并且反序列化和迭代如下:

      var input = @"{""name"":""test"",""clients"": {""client1"": {""id"": ""1"", ""count"": ""41""},""client2"": {""name"": ""testName""},""client3"": {""CustomerID"": ""a1"", ""internalID"": ""testID""}}}";
      var foo = JsonConvert.DeserializeObject<Foo>(input);
      foreach (var item in foo.clients)
      {
          Console.WriteLine(item.Key);
      }
      

      输出:

      client1
      client2
      client3
      

      Example on DotNetFiddle

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-08-09
        • 2013-05-15
        • 2021-08-02
        • 1970-01-01
        • 1970-01-01
        • 2020-03-07
        • 1970-01-01
        相关资源
        最近更新 更多