我试图在c#对象中实现json结构,并且试图了解如何根据类型使用正确的对象。例如:
public class RootObject
{
public string name { get; set; }
public Content content { get; set; }
}
public class Content
{
public string id{ get; set; }
public string type { get; set; }
public Dictionary<string, Item> child { get; set; }
}
public class Item
{
public string id { get; set; }
public string type { get; set; }
public List<string> model { get; set;}
public string[] color {get; set;}
}
请注意,这只是一个示例,每个对象都有更多的属性。如果Json包含type =“ Boy”,我该如何生成男孩对象。
示例JSON:
string json = @"
{
'name': 'Object 1',
'content': {
'body': {
'id': 'body',
'type': 'Body'
},
'style': {
'id': 'style',
'type': 'Style'
},
'DynamicName-123': {
'id': 'DynamicName-123',
'type': 'Row'
'model': {},
'colors': []
},
'DynamicName-434': {
'id': 'DynamicName-434',
'type': 'Column'
'model': {},
'colors': []
},
'DynamicName-223': {
'id': 'DynamicName-223',
'type': 'Item'
'model': {},
'colors': []
}
}
}";
答案 0 :(得分:1)
如果您的键/值对不是固定的,并且数据必须可配置,则Newtonsoft.json具有一项要在此处使用的功能,即 [JsonExtensionData]
Read more < / p>
现在,序列化对象时将写入扩展数据。读取和写入扩展数据可以自动往返所有JSON,而无需将所有属性添加到要反序列化的.NET类型。仅声明您感兴趣的属性,然后让扩展数据完成其余工作。
在您的情况下,假设有一个课程,
public class MyClass
{
public string Qaz { get; set; }
public string Wsx { get; set; }
[JsonExtensionData]
public Dictionary<string, JToken> child { get; set; }
public MyClass()
{
child = new Dictionary<string, JToken>();
}
}
在上面的类中,您知道Qaz
和Wsx
始终存在于您的json中,它们包含value或null,
但是对于动态数据,您无法说出将从json接收到哪个键/值对,因此[JsonExtensionData]
可以将所有这些键/值对收集到字典中。
假设以下类别适用于您的动态数据,
public class ABC
{
public string Abc { get; set; }
}
public class PQR
{
public string Pqr { get; set; }
}
public class XYZ
{
public string Xyz { get; set; }
}
序列化:
ABC aBC = new ABC { Abc = "abc" };
PQR pQR = new PQR { Pqr = "pqr" };
XYZ xYZ = new XYZ { Xyz = "xyz" };
MyClass myClass = new MyClass();
myClass.Qaz = "qaz";
myClass.Wsx = "wsx";
myClass.child.Add("ABC", JToken.FromObject(aBC));
myClass.child.Add("PQR", JToken.FromObject(pQR));
myClass.child.Add("XYZ", JToken.FromObject(xYZ));
string outputJson = JsonConvert.SerializeObject(myClass);
这会给你像json
{
"Qaz": "qaz",
"Wsx": "wsx",
"ABC": {
"Abc": "abc"
},
"PQR": {
"Pqr": "pqr"
},
"XYZ": {
"Xyz": "xyz"
}
}
反序列化:
MyClass myClass = JsonConvert.DeserializeObject<MyClass>(outputJson);
string Qaz = myClass.Qaz;
string Wsx = myClass.Wsx;
if (myClass.child.ContainsKey("ABC"))
{
ABC abcObj = myClass.child["ABC"].ToObject<ABC>();
}
if (myClass.child.ContainsKey("PQR"))
{
PQR pqrObj = myClass.child["PQR"].ToObject<PQR>();
}
if (myClass.child.ContainsKey("XYZ"))
{
XYZ pqrObj = myClass.child["XYZ"].ToObject<XYZ>();
}
结论: [JsonExtensionData]
的主要目的是使json类层次结构保持简单和可读性,因此您无需为每个属性。
使用Dictionary中的JToken中的特定键获取所有动态数据:
您可以使用LINQ从上述字典中获取特定键的所有动态数据。
var allAbcTypes = myClass.child
.SelectMany(x => x.Value
.ToObject<JObject>()
.Properties()
.Where(p => p.Name == "Abc") //<= Use "Column" instead of "Abc"
.Select(o => new ABC //<= Use your type that contais "Column" as a property
{
Abc = o.Value.ToString()
})).ToList();
在您的情况下,类似
var allColumnTypes = myClass.child
.SelectMany(x => x.Value
.ToObject<JObject>()
.Properties()
.Where(p => p.Name == "Column")
.Select(o => new Item
{
id = x.Value["id "].ToString(),
type = x.Value["type "].ToString(),
model = x.Value["model"].ToObject<List<string>>(),
color = x.Value["color"].ToObject<string[]>()
})).ToList();
答案 1 :(得分:0)
如果您想反序列化为包含键字符串和动态值的字典(在这种情况下为男孩或女孩),我知道的唯一方法是使用动态类:
ui <- fluidPage(
dashboardPage(
dashboardHeader(),
dashboardSidebar(width = 0),
dashboardBody(
fluidRow(
box(plotOutput("plot1", height = 400), width = 12)
)
)
)
)