代码之家  ›  专栏  ›  技术社区  ›  CularBytes

将活动活动活动的漂亮JSON输出反序列化为C对象

  •  1
  • CularBytes  · 技术社区  · 5 年前

    “美丽”在这里是讽刺的。

    当您调用活动活动的 list_view 端点,并希望在JSON响应中得到它,那么这就是您得到的JSON响应:

    {
        "0": {
            "id": "4",
            "name": "Nieuwsletter 1",
            "cdate": "2018-11-22 03:44:19",
            "private": "0",
            "userid": "6",
            "subscriber_count": 2901
        },
        "1": {
            "id": "5",
            "name": "Newsletter 2",
            "cdate": "2018-11-22 05:02:41",
            "private": "0",
            "userid": "6",
            "subscriber_count": 2229
        },
        "2": {
            "id": "6",
            "name": "Newsletter 3",
            "cdate": "2018-11-22 05:02:48",
            "private": "0",
            "userid": "6",
            "subscriber_count": 638
        },
        "result_code": 1,
        "result_message": "Success: Something is returned",
        "result_output": "json"
    }
    

    现在,我如何能够将它反序列化为一个对象呢?执行普通编辑=>选择性粘贴=>将JSON粘贴为类会给我一个输出,在该输出中,我最终得到一个名为 _2 .

    此外,jsonConvert还引发以下错误: Accessed JObject values with invalid key value: 2. Object property name expected. 所以它也不能真正地反序列化它。我试着用 dynamic 作为要转换为的对象类型。

    我现在唯一能想到的就是替换第一个 { 通过 [ 最后一个 } 通过 ] ,然后删除所有 "1" : 然后删除最后3个属性。之后我有了一个简单的可转换的基本数组。但我希望有人能有更好的解决方案,而不是深入到string.indexof和string.replace party…

    2 回复  |  直到 5 年前
        1
  •  3
  •   er-sho    5 年前

    如果您的键/值对不是固定的,并且数据必须是可配置的,那么newtonsoft.json有一个特性可以在这里使用,即 [JsonExtensionData] . Read more

    扩展数据现在在对象序列化时写入。读取和写入扩展数据可以自动往返所有JSON,而无需将每个属性添加到重新反序列化到的.NET类型中。只声明您感兴趣的属性,让扩展数据完成其余的工作。

    在您的情况下,键/值与 0,1,2,3.......N 拥有动态数据,这样您的类将

    因此,创建一个属性来收集具有该属性的所有动态键/值对。 [jsonextensiondata] . 下面我用名字创造了一个 DynamicData .

    class MainObj
    {
        [JsonExtensionData]
        public Dictionary<string, JToken> DynamicData { get; set; }
    
        public int result_code { get; set; }
        public string result_message { get; set; }
        public string result_output { get; set; }
    }
    

    然后您可以像

    string json = "Your json here"
    
    MainObj mainObj = JsonConvert.DeserializeObject<MainObj>(json); 
    

    编辑:

    如果要将动态键的值收集到类中,则可以在类结构下面使用。

    class MainObj
    {
        [JsonExtensionData]
        public Dictionary<string, JToken> DynamicData { get; set; }
    
        [JsonIgnore]
        public Dictionary<string, ChildObj> ParsedData
        {
            get
            {
                return DynamicData.ToDictionary(x => x.Key, y => y.Value.ToObject<ChildObj>());
            }
        }
    
        public int result_code { get; set; }
        public string result_message { get; set; }
        public string result_output { get; set; }
    }
    
    public class ChildObj
    {
        public string id { get; set; }
        public string name { get; set; }
        public string cdate { get; set; }
        public string _private { get; set; }
        public string userid { get; set; }
        public int subscriber_count { get; set; }
    }
    

    然后您可以像

    MainObj mainObj = JsonConvert.DeserializeObject<MainObj>(json);
    

    然后您可以访问每一个反序列化的数据,比如

    int result_code = mainObj.result_code;
    string result_message = mainObj.result_message;
    string result_output = mainObj.result_output;
    
    foreach (var item in mainObj.ParsedData)
    {
        string key = item.Key;
        ChildObj childObj = item.Value;
    
        string id = childObj.id;
        string name = childObj.name;
        string cdate = childObj.cdate;
        string _private = childObj._private;
        string userid = childObj.userid;
        int subscriber_count = childObj.subscriber_count;
    }
    
        2
  •  2
  •   Andrew Skirrow    5 年前

    我建议 JObject Newtonsoft.Json 图书馆

    例如,使用C Interactive

    // Assuming you've installed v10.0.1 of Newtonsoft.Json using a recent version of nuget
    #r "c:\Users\MyAccount\.nuget\.nuget\packages\Newtonsoft.Json\10.0.1\lib\net45\Newtonsoft.Json.dll"
    
    using Newtonsoft.Json.Linq;
    var jobj = JObject.Parse(File.ReadAllText(@"c:\code\sample.json"));
    foreach (var item in jobj)
    {
         if (int.TryParse(item.Key, out int value))
         {
             Console.WriteLine((string)item.Value["id"]);
    
             // You could then convert the object to a strongly typed version
             var listItem = item.Value.ToObject<YourObject>();
          }
    }
    

    输出:

     4
     5
     6
    

    有关详细信息,请参阅此页

    https://www.newtonsoft.com/json/help/html/QueryingLINQtoJSON.htm