如何将对象树反序列化为DTO?

时间:2019-03-28 17:37:49

标签: c# .net json json.net

我正在尝试反序列化返回到DTO的JSon对象树。该树最多可以有4个级别的深度,并超过1200个节点。该代码是使用Newtonsoft.Json进行反序列化的C#代码。

编辑

JSon看起来像:

[
{
    "id": 1095,
    "name": "Item1-1",
    "children": [
        {
            "id": 1097,
            "name": "Item2-2",
            "children": [
                {
                    "id": 18,
                    "name": "Item3-3",
                    "children": [
                        {
                            "id": 19,
                            "name": "Item4-4",
                            "children": [],
                            "level": 4,
                            "parentId": 18
                        },
                        {
                            "id": 20,
                            "name": "Item5-4",
                            "children": [],
                            "level": 4,
                            "parentId": 18
                        }
                    ],
                    "level": 3,
                    "parentId": 1097
                }
                ],
                "level": 2,
                "parentId": 1095
        }
    ],
    "level": 1,
    "parentId": null
}
]

我的DTO与此类似:

public class MyDTO
{
    [JsonProperty("id")]
    public int Id { get; set; }
    [JsonProperty("name")]
    public string Name { get; set; }
    [JsonProperty("children")]
    public MyDTO[] Children { get; set; }
    [JsonProperty("level")]
    public int Level { get; set; }
    [JsonProperty("parentId")]
    public int ParentId { get; set; }

    public MyDTO()
    {
    }
}

在此链接中,我喜欢Brian Rogers的解决方案,该解决方案将json反序列化为对象: How do I use JSON.NET to deserialize into nested/recursive Dictionary and List?

 public static class JsonHelper
{
    public static object Deserialize(string json)
    {
        return ToObject(JToken.Parse(json));
    }

    private static object ToObject(JToken token)
    {
        switch (token.Type)
        {
            case JTokenType.Object:
                return token.Children<JProperty>()
                            .ToDictionary(prop => prop.Name,
                                          prop => ToObject(prop.Value));

            case JTokenType.Array:
                return token.Select(ToObject).ToList();

            default:
                return ((JValue)token).Value;
        }
    }
}

我用object obj = JsonHelper.Deserialize(jsonString);调用JSonHelper

我一直在尝试将此代码转换为可转换为MyDTO的方法,但我一直遇到编译器错误。我试图简单地使用MyDTO转换JValue强制转换,然后转到具有列表的列表。

我的目标是调用MyDTO obj = JsonHelp.Deserialize(jsonString)并返回MyDTO对象树。是否可以做我想做的事情,还是应该找到一种将每个对象投射到MyDTO的方法?

1 个答案:

答案 0 :(得分:4)

首先,您的JSON缺少brakcet ],然后您的模型需要可为空的parentId。进行一些简单的更改即可JsonConvert.DeserializeObject<IEnumerable<MyDTO>>(json)

因此您的JSON应该如下所示:

[
{
    "id": 1095,
    "name": "Item1-1",
    "children": [
        {
            "id": 1097,
            "name": "Item2-2",
            "children": [
                {
                    "id": 18,
                    "name": "Item3-3",
                    "children": [
                        {
                            "id": 19,
                            "name": "Item4-4",
                            "children": [],
                            "level": 4,
                            "parentId": 18
                        },
                        {
                            "id": 20,
                            "name": "Item5-4",
                            "children": [],
                            "level": 4,
                            "parentId": 18
                        }
                    ],
                    "level": 2,
                    "parentId": 1095
                }],
            }],
    "level": 1,
    "parentId": null
}
]

并且可以使用此模型反序列化:

public class MyDTO
{
    public int Id { get; set; }
    public string Name { get; set; }
    public MyDTO[] Children { get; set; }
    public int Level { get; set; }
    public int? ParentId { get; set; }
}

使用此代码:

var dto = JsonConvert.DeserializeObject<IEnumerable<MyDTO>>(json);