使用root中的数字对象反序列化JSON

时间:2018-06-15 07:58:50

标签: c# json.net

我收到以下JSON:

{
"1": {
    "startDate": "",
    "endDate": "",
    "projectId": 10000,
    "build": "",
    "totalExecutions": 1,
    "totalExecuted": 1,
    "environment": "",
    "description": "Audit Test Cycle",
    "executionSummaries": {
        "executionSummary": [
            {
                "count": 0,
                "statusKey": -1,
                "statusName": "UNEXECUTED",
                "statusColor": "#A0A0A0",
                "statusDescription": "The test has not yet been executed."
            },
            {
                "count": 1,
                "statusKey": 1,
                "statusName": "PASS",
                "statusColor": "#75B000",
                "statusDescription": "Test was executed and passed successfully."
            },
            {
                "count": 0,
                "statusKey": 2,
                "statusName": "FAIL",
                "statusColor": "#CC3300",
                "statusDescription": "Test was executed and failed."
            },
            {
                "count": 0,
                "statusKey": 3,
                "statusName": "WIP",
                "statusColor": "#F2B000",
                "statusDescription": "Test execution is a work-in-progress."
            },
            {
                "count": 0,
                "statusKey": 4,
                "statusName": "BLOCKED",
                "statusColor": "#6693B0",
                "statusDescription": "The test execution of this test was blocked for some reason."
            }
        ]
    },
    "name": "Audit Test Cycle",
    "expand": "executionSummaries",
    "versionId": 10000,
    "started": ""
},
"2":  {
    "startDate": "",
    "endDate": "",
    "projectId": 10000,
    "build": "",
    "totalExecutions": 1,
    "totalExecuted": 1,
    "environment": "",
    "description": "Audit Test Cycle",
    "executionSummaries": {
        "executionSummary": [
            {
                "count": 0,
                "statusKey": -1,
                "statusName": "UNEXECUTED",
                "statusColor": "#A0A0A0",
                "statusDescription": "The test has not yet been executed."
            },
            {
                "count": 1,
                "statusKey": 1,
                "statusName": "PASS",
                "statusColor": "#75B000",
                "statusDescription": "Test was executed and passed successfully."
            },
            {
                "count": 0,
                "statusKey": 2,
                "statusName": "FAIL",
                "statusColor": "#CC3300",
                "statusDescription": "Test was executed and failed."
            },
            {
                "count": 0,
                "statusKey": 3,
                "statusName": "WIP",
                "statusColor": "#F2B000",
                "statusDescription": "Test execution is a work-in-progress."
            },
            {
                "count": 0,
                "statusKey": 4,
                "statusName": "BLOCKED",
                "statusColor": "#6693B0",
                "statusDescription": "The test execution of this test was blocked for some reason."
            }
        ]
    },
    "name": "Audit Test Cycle",
    "expand": "executionSummaries",
    "versionId": 10000,
    "started": ""
},
"3":  {
    "startDate": "",
    "endDate": "",
    "projectId": 10000,
    "build": "",
    "totalExecutions": 1,
    "totalExecuted": 1,
    "environment": "",
    "description": "Audit Test Cycle",
    "executionSummaries": {
        "executionSummary": [
            {
                "count": 0,
                "statusKey": -1,
                "statusName": "UNEXECUTED",
                "statusColor": "#A0A0A0",
                "statusDescription": "The test has not yet been executed."
            },
            {
                "count": 1,
                "statusKey": 1,
                "statusName": "PASS",
                "statusColor": "#75B000",
                "statusDescription": "Test was executed and passed successfully."
            },
            {
                "count": 0,
                "statusKey": 2,
                "statusName": "FAIL",
                "statusColor": "#CC3300",
                "statusDescription": "Test was executed and failed."
            },
            {
                "count": 0,
                "statusKey": 3,
                "statusName": "WIP",
                "statusColor": "#F2B000",
                "statusDescription": "Test execution is a work-in-progress."
            },
            {
                "count": 0,
                "statusKey": 4,
                "statusName": "BLOCKED",
                "statusColor": "#6693B0",
                "statusDescription": "The test execution of this test was blocked for some reason."
            }
        ]
    },
    "name": "Audit Test Cycle",
    "expand": "executionSummaries",
    "versionId": 10000,
    "started": ""
},
"recordsCount": 3}

}

其中一个根对象是recordcount,但其他的是数字。这些数字很重要,所以我不能放松它们。数字不是以1递增,它可以是8,5,2,4,6或任何其他组合(但唯一!)。

我想将它们反序列化为以下类,但不知道如何处理该数字。

public class Cycles //: Dictionary<string,Cycle>
{
    public Dictionary<string,Cycle> cycles { get; set; }
    public int recordsCount { get; set; } 
}


public class Cycle 
{
    public int totalExecutions { get; set; }
    public string endDate { get; set; }
    public string description { get; set; }
    public int totalExecuted { get; set; }
    public string started { get; set; }
    public string versionName { get; set; }
    public string expand { get; set; }
    public string projectKey { get; set; }
    public int versionId { get; set; }
    public string environment { get; set; }
    public string build { get; set; }
    public string createdBy { get; set; }
    public string ended { get; set; }
    public string name { get; set; }
    public string modifiedBy { get; set; }
    public int projectId { get; set; }
    public string createdByDisplay { get; set; }
    public string startDate { get; set; }
}

我知道JSON并不好,但我无法改变它。它来自第三方工具。

通常我会做

return _jsonDeserializer.Deserialize<Cycles>(response);

但这不起作用。 所以我试着不用它来“反序列化”:

Cycles result = new Cycles();
        JObject jsonOb = JObject.Parse(response.Content);
        result.recordsCount = jsonOb.Value<int>("recordsCount");
        jsonOb.Remove("recordsCount");
        var values = jsonOb.ToObject<Dictionary<string,Cycle>>();
        result.cycles = values;

我可以获取“recordscount”数据,但在尝试创建词典时,我收到错误

error CS0119: 'Dictionary<string, Cycle>' is a type, which is not valid in the given contex

1 个答案:

答案 0 :(得分:4)

如果我们在JSON中没有using System; using System.Collections.Generic; using System.IO; using System.Linq; using Newtonsoft.Json.Linq; class Test { static void Main() { var json = File.ReadAllText("test.json"); var parsed = JObject.Parse(json); var cycles = new Cycles { cycles = parsed.Properties() .Where(p => int.TryParse(p.Name, out _)) .ToDictionary(p => p.Name, p => p.Value.ToObject<Cycle>()), recordsCount = (int) parsed["recordsCount"] }; Console.WriteLine(string.Join(", ", cycles.cycles.Keys)); } } 属性,那么它将相当简单。实际上,我怀疑最简单的方法是首先使用LINQ to JSON,找出哪些值属于字典,并要求JSON.NET转换每个...但填充顶部 - 对象你自己。 (这很像你已经尝试过的,看起来很像。)

以下是一个适用于您的示例数据和类的示例:

[JsonProperty]

顺便说一句,我建议将所有属性重命名为惯用的C#,并使用datetime.time指定JSON中使用的名称。