Json.net 反序列化具有不同名称的相同对象

Json.net deserialize same objectcts with different names

我正在使用 Json.net 反序列化现有服务中的 JSON 数据。 样本:

{
    "id" : 3223,
    "name" : "position 3223",
    "containers" : {
        "container_demo" : {
            "id" : 12,
            "name" : "demo",
            "value" : 34
        },
        "different_name_1" : {
            "id" : 33,
            "name" : "demo 3",
            "value" : 1
        },
        "another_contaier" : {
            "id" : 1,
            "name" : "another demo",
            "value" : 34
        }
    }
}

正如我们所见,我们在 container 对象中具有相同的结构和不同的对象名称。 目标是将 containers 反序列化为 Container 个对象的数组:

public class Root
{
    public int id {set;get;}
    public string name {set;get;}
    Array<Container> containers {set;get;}
}

public class Container
{
    public int id {set; get;}
    public string name {set;get;}
    public int value {set;get;}
}

如何解决?是否可以使用 CustomCreationConverter<T> 正确反序列化?

更新

鉴于你更新的 classes 和更新的 JSON,你会做:

public class RootObject
{
    public Root root { get; set; }
}

public class Root
{
    public int id {set;get;}
    public string name {set;get;}
    public Dictionary<string, Container> containers { get; set; }
}

public class Container
{
    public int id {set; get;}
    public string name {set;get;}
    public int value {set;get;}
}

并像这样使用它:

        var root = JsonConvert.DeserializeObject<RootObject>(json);

请注意 JSON 中的 "root" 属性 需要额外的间接级别,我们由 RootObject class 提供。您可能想将 Root 重命名为更具描述性的名称,例如 RootContainer.

更新 2

题中的JSON再次修改,去掉了"root"属性,所以RootObject不需要,只需要做:

        var root = JsonConvert.DeserializeObject<Root>(json);

原答案

假设您的嵌套 containers 也是 Container 类型,您可以将它们反序列化为 Dictionary<string, Container> 属性:

public class Container
{
    public int id { set; get; }
    public string name { set; get; }
    public int? value { set; get; } // Null when the property was not present in the JSON.
    public Dictionary<string, Container> containers { get; set; }
}

你会像这样使用它:

    public static void Test()
    {
        string json = @"
        {
            ""id"" : 3223,
            ""name"" : ""position 3223"",
            ""containers"" : {
                ""container_demo"" : {
                    ""id"" : 12,
                    ""name"" : ""demo"",
                    ""value"" : 34
                },
                ""different_name_1"" : {
                    ""id"" : 33,
                    ""name"" : ""demo 3"",
                    ""value"" : 1
                },
                ""another_contaier"" : {
                    ""id"" : 1,
                    ""name"" : ""another demo"",
                    ""value"" : 34
                }
            }
        }";

        var container = JsonConvert.DeserializeObject<Container>(json);

        JsonSerializerSettings settings = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore };

        Debug.WriteLine(JsonConvert.SerializeObject(container, Formatting.Indented, settings));
    }

这会产生输出:

{
  "id": 3223,
  "name": "position 3223",
  "containers": {
    "container_demo": {
      "id": 12,
      "name": "demo",
      "value": 34
    },
    "different_name_1": {
      "id": 33,
      "name": "demo 3",
      "value": 1
    },
    "another_contaier": {
      "id": 1,
      "name": "another demo",
      "value": 34
    }
  }

可以看到,所有数据都反序列化,序列化成功

试试这样的数据结构-

public class Holder
{
    public int id { set; get; }

    public string name { set; get; }

    public Dictionary<string, Container> containers{ get; set; }
}


public class Container
{
    public int id { set; get; }

    public string name { set; get; }

    public int value { set; get; }
}

并将 json 反序列化为 Holder class.

var holders = JsonConvert.DeserializeObject<Holder> (json);