【问题标题】:How to deserialize complex JSON with dynamic keys in asp.net core?如何在 asp.net 核心中使用动态键反序列化复杂的 JSON?
【发布时间】:2019-05-12 01:18:58
【问题描述】:

我有一个看起来像这样的复杂 JSON:

{
    "results": [
        {
            "statement_id": 0,
            "series": [
                {
                    "name": "test-name",
                    "tags": {
                        "tag1": "0"
                        "tag2": "1"
                    },
                    "columns": [
                        "time",
                        "mean"
                    ],
                    "values": [
                        [
                            "2018-12-03T10:18:37.3Z",
                            0
                        ]
                    ]
                }
            ]
        }
    ]
}

上面的POCO是这样的:

public class Tags
{
    public string tag1 { get; set; }
    public string tag2 { get; set; }
}

public class Series
{
    public string name { get; set; }
    public Tags tags { get; set; }
    public List<string> columns { get; set; }
    public List<List<object>> values { get; set; }
}

public class Result
{
    public int statement_id { get; set; }
    public List<Series> series { get; set; }
}

public class RootObject
{
    public List<Result> results { get; set; }
}

问题是,Tags 类中的属性是动态的。可以只有一个标签,2 个或更多标签,仅在运行时确定。

我正在尝试使用 Newtonsoft.Json 将其解析为像 Dictionary&lt;string, &lt;Dictionary&lt;string, object[]&gt;&gt;&gt; 这样的嵌套字典,其中字典的键是标签的值,object[] 包含值列表(只是值,而不是时间戳)。

【问题讨论】:

  • 您能摆脱Tags 类,而是将其添加为标签的属性吗? public IDictionary&lt;string, JToken&gt; Tags { get; set; }

标签: c# json asp.net-core-2.1 .net-core-2.1


【解决方案1】:

你应该使用 Dictionary 而不是 Tag Class。

[JsonExtensionData]
public Dictionary<string,object> Tags{get;set;}

例如,

public class JsonSample
{
[JsonExtensionData]
public Dictionary<string,object> RandomKeyValuePair {get;set;}
}

// Sample Code
var jsonString = @"
{
'Key1' : 'some value 1',
'Key2' : 'some value 1',
'Key3' : 'some value 1',
'Key4' : 'some value 1',
}";



var jsonSampleObject = JsonConvert.DeserializeObject<JsonSample>(jsonString);

更新

修改后的系列类

public class Series
{
    public string name { get; set; }
    [JsonExtensionData]
    public IDictionary<string,JToken> tags { get; set; }
    public List<string> columns { get; set; }
    public List<List<object>> values { get; set; }
}

客户电话

var result = JsonConvert.DeserializeObject<RootObject>(str);
Console.WriteLine(String.Join(",",result.results.First().series.First().tags.Select(x=>$"{x.Key}={x.Value},")));

输出

tags={
  "tag1": "0",
  "tag2": "1"
},

请注意您的 Json 中有错误。在“tag1”之后缺少“,”:“0”

【讨论】:

  • 这与简单的JsonConvert.DeserializeObject&lt;IDictionary&lt;string, object&gt;&gt;(json) 有何不同?看不出这对我有什么帮助。
  • 考虑一个比示例中显示的更复杂的数据类型,可能与您的类似。在那种情况下,这也是可行的。
  • 你能告诉我你将如何使用我的 json 模式而不是你展示的这个简单的例子来做到这一点吗?
  • @swdon 我已经用您的数据结构的示例代码更新了答案
【解决方案2】:

仅将 Series 类中的 tags 属性数据类型从

public Tags tags { get; set; }

public Dictionary<string, JToken> tags { get; set; }

然后你就可以从你的 json 解析动态键标签了。

所以你的Series 课程将是。

public class Series
{
    public string name { get; set; }
    public Dictionary<string, JToken> tags { get; set; }
    public List<string> columns { get; set; }
    public List<List<object>> values { get; set; }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-11-11
    • 2014-04-07
    • 1970-01-01
    • 2022-07-08
    • 2023-01-17
    • 1970-01-01
    相关资源
    最近更新 更多