gpt4 book ai didi

c# - Json 到 C# 对象处理动态属性

转载 作者:行者123 更新时间:2023-11-30 17:27:03 25 4
gpt4 key购买 nike

我正在尝试在 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': []
}
}
}";

最佳答案

如果您的键/值对不固定并且数据必须是可配置的,那么 Newtonsoft.json 有一项功能可以在这里使用,即 [JsonExtensionData] Read more

Extension data is now written when an object is serialized. Reading and writing extension data makes it possible to automatically round-trip all JSON without adding every property to the .NET type you’re deserializing to. Only declare the properties you’re interested in and let extension data do the rest.

在你的例子中,假设有一个类,

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>();
}
}

在上面的类(class)中,您知道 QazWsx 始终存在于您的 json 中,它们包含值或 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 类层次结构简单且更具可读性,因此您不需要管理每个属性的类结构。

通过字典中的 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();

关于c# - Json 到 C# 对象处理动态属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55569424/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com