我有一个COMPLEX JSON,我需要反序列化并访问其所有对象。我的JSON看起来像这样
{
"name": {},
"percentage": [
{
"math": {
"2.503300099.1": 460800,
"2.503300099.2": 460800,
"2.503300099.3": 460800,
"2.503308292.1": 2457600,
"2.503308292.2": 2457600,
"2.503308292.3": 2457600
},
"english": {
"2.503300099": "hello",
"2.503308292": "hi"
},
"exam": "2.0"
}
],
"class": {},
"section": "7.17.1",
"total": 1
}
JSON的值可能会改变,它们出现的次数也可能会改变。
到目前为止我可以访问的是名称,类别,部分,总数和问题是百分比部分。我也可以达到百分比,但我无法访问数学或英语,或者考试他们的价值观。
string content = await response.Content.ReadAsStringAsync();
JObject Search = JObject.Parse(content);
Speed res = new Speed();
res.class= Search["class"].ToString(); // good
res.english = Search["english"].ToString();// not good
请提供任何帮助或建议吗?
修改
在关于JSON结构的这么多问题之后,我想澄清一下这个结构不会改变,但是对象的数量可能会让我们用一个例子来理解:
{
"One": {},
"Two": [
{
"twoA": {
"2.503300099.1": 460800,
"2.503300099.2": 460800,
"...." : ...,
"...." : ...,
},
"TwoB": {
"2.503300099": "value",
"2.503308292": "value"
"...." : ...,
"...." : ...,
},
"TwoC": {
"2.503300099": "value",
"2.503308292": "value"
"...." : ...,
"...." : ...,
},
"exam": "2.0",
"...." : ...,
"...." : ...,
}
],
"Three": {empty},
"Four": "value string",
"Five": value int
.....
.....
}
希望这能澄清对JSON结构的怀疑
答案 0 :(得分:1)
从对您的问题和后续答案的评论来看,似乎来自API的数据是不可预测的,因为我开始争论负责该API的人应该退后一步并重新考虑他们的方法。我没有看到如何解析任何数据,而没有提示如何构建数据。
但也许我反应过度了......
也许将数据解析为dynamic
是您正在寻找的答案?使用这种方法,您可以执行以下操作:
const string data = "{\"1123.5433\":{\"42.42.42\":\"bazinga\"}}";
var myDynamic = JsonConvert.DeserializeObject<dynamic>(data);
Console.WriteLine(myDynamic["1123.5433"]["42.42.42"]); // -> bazinga;
示例中math
中值的路径,如果我没记错的话,就像这样:
myDynamic["percentage"][0]["math"]["2.503300099.1"]; // ~ 460800?
虽然不太可读。还是稳定的所以,我居住,回过头来思考我最初的困惑,那就是有什么样的生物想到了有问题的API ......
编辑:更新以反映原始问题中的评论和更改:
// First example
const string originalExample =
"{\"name\": {},\"percentage\": [{\"math\": {\"2.503300099.1\": 460800,\"2.503300099.2\": 460800},\"english\": {\"2.503300099\": \"hello\"}}]}";
var myFirstDynamic = JsonConvert.DeserializeObject<dynamic>(originalExample);
Console.WriteLine(myFirstDynamic["percentage"][0]["math"]["2.503300099.1"]); // -> 460800
// Second example
const string newExample =
"{\"One\": {},\"Two\": [{\"twoA\": {\"2.503300099.1\": 460800,\"2.503300099.2\": 460800,},\"TwoB\": {\"2.503300099\": \"value\",\"2.503308292\": \"value\"},\"TwoC\": {\"2.503300099\": \"value\",\"2.503308292\": \"value\"},\"exam\": \"2.0\"}]}";
var mySecondDynamic = JsonConvert.DeserializeObject<dynamic>(newExample);
Console.WriteLine(mySecondDynamic["Two"][0]["twoA"]["2.503300099.1"]); // -> 460800;
鉴于您在第二个示例中提供的结构,您还可以定义合适的类型以适合相同的结构:
public class MyObject
{
public IEnumerable<MyNextObject> Two { get; set; }
}
public class MyNextObject
{
public dynamic twoA { get; set; }
}
然后你可以像这样反序列化和解析:
var deserializedToType = JsonConvert.DeserializeObject<MyObject>(newExample);
Console.WriteLine(deserializedToType.Two.First().twoA["2.503300099.1"]); // -> 460800;
由于源数据中的属性名称对C#无效,因此您仍需要在出现问题的地方输入dynamic
(例如MyNextObject.twoA
)。此外,根据您正在尝试做的事情以及在什么情况下,枚举percentage
等子项可能是比选择特定索引更好的选择。
请注意,我使用的是与我在所有示例中提供的完全相同的json结构,虽然为了简洁而最终缩短并转义为提供工作示例。
如果您的源属性名称不一致,无效或不遵守常见的实践,为了保持您的C#代码干净,您应该使用某种方法在源和目标之间映射值。例如。如果你正在使用Json.NET,那就像JsonProperty
属性。
另外,请注意,我不是在这里展示“代码生产”。显然,您应该注意并妥善处理潜在问题,例如null
值或超出范围的索引。