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);
我正在使用 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);