C# 无法确定JSON数据的数据结构
我有以下JSON文件,在解析时遇到问题C# 无法确定JSON数据的数据结构,c#,json,json.net,C#,Json,Json.net,我有以下JSON文件,在解析时遇到问题 { "version": 2, "versioned_files": [ { "DB": [ "Table0", [ { "version": 0, "fields": [ {
{
"version": 2,
"versioned_files": [
{
"DB": [
"Table0",
[
{
"version": 0,
"fields": [
{
"name": "key",
"type": "StringU8"
},
{
"name": "value",
"type": "Float"
}
],
"localised": []
}
]
]
},
{
"NoDbObject": [
{
"version": 1,
"fields": [
{
"name": "objectProp",
"type": "StringU8"
}
],
"localised": []
}
]
}
]
}
为我生成以下代码,这不是很有帮助:
// Root myDeserializedClass = JsonConvert.DeserializeObject(myJsonResponse);
public class Root
{
public int version { get; set; }
public List<List<object>> files { get; set; }
}
//根myDeserializedClass=JsonConvert.DeserializeObject(myJsonResponse);
公共类根
{
公共int版本{get;set;}
公共列表文件{get;set;}
}
我尝试过的大多数操作都给了我一个空文件列表或以下错误:
Newtonsoft.Json.JsonSerializationException:无法将当前JSON数组(例如[1,2,3])反序列化为类型“RonParser.VersionedFile”,因为该类型需要一个JSON对象(例如{“name”:“value”})才能正确反序列化。 要修复此错误,请将JSON更改为JSON对象(例如{“name”:“value”}),或将反序列化类型更改为数组或实现可从JSON数组反序列化的集合接口(例如ICollection、IList)类似列表的类型。还可以将JsonArrayAttribute添加到类型中,以强制它从JSON数组反序列化。 路径“文件[0]”,第4行,位置5
这里如何构造数据对象?我不得不说,这是我在野外见过的一种更不友好的JSON格式。主要问题是一些数组包含混合类型,这使得很难声明类来表示它们。JSON类生成器通常不知道在这种情况下该做什么,所以它们默认使用
List
,如您所见。很多时候,您需要自己提出一个合理的类模型,然后使用自定义来填充它
以下是我为您的JSON提出的模型:
class RootObject
{
public int Version { get; set; }
[JsonProperty("versioned_files")]
public List<VersionedFile> VersionedFiles { get; set; }
}
[JsonConverter(typeof(VersionedFileConverter))]
class VersionedFile
{
public string Key { get; set; }
public string Label { get; set; }
public List<Item> Items { get; set; }
}
class Item
{
public int Version { get; set; }
public List<Field> Fields { get; set; }
public List<object> Localised { get; set; }
}
class Field
{
public string Name { get; set; }
public string Type { get; set; }
}
所有这些就绪后,我们可以像这样反序列化和转储数据:
var root = JsonConvert.DeserializeObject<RootObject>(json);
Console.WriteLine("Root version: " + root.Version);
Console.WriteLine("Versioned files:");
foreach (var vf in root.VersionedFiles)
{
Console.WriteLine(" Key: " + vf.Key);
Console.WriteLine(" Label: " + (vf.Label ?? "(none)"));
Console.WriteLine(" Items:");
foreach (var item in vf.Items)
{
Console.WriteLine(" Version: " + item.Version);
Console.WriteLine(" Fields:");
foreach (var field in item.Fields)
{
Console.WriteLine(" Field name: " + field.Name);
Console.WriteLine(" Field type: " + field.Type);
Console.WriteLine();
}
}
}
这里的工作演示:所有
字段类型
都是错误的,应该是“字段类型”:“uint8”
,“string”
等。始终验证JSON输入,作为调试的第一步。你的无效。不要依赖代码生成器。虽然这些工具可以派上用场,但除非您了解如何手工编写输出,否则绝对不应该使用这些工具。@Franzgleichman我已经验证了该文件,但我做了一些手动编辑,因此我不必发布100k行文件,在那里犯了一个小错误。更新问题并感谢您指出。使用更新的json
尝试强制转换,如Root myDeserializedClass=JsonConvert.DeserializeObject(myJsonResponse)代码>我认为,这根myDeserializedClass=JsonConvert.DeserializeObject(myJsonResponse)代码>将显示生成错误。或者将代码>根/代码>改为DyAm或Objor。如果数组是异构的,则可以考虑将其声明为<代码>动态[]/COD>。您还可以使用工作接近完美的Newtonsoft.Json.Linq.Object[]
,但在运行它时,我注意到我的数组中还有两个其他对象。它们不包含“table name”属性,但除此之外,它们是相同的。有办法处理吗?我已经更新了原始问题以反映新的对象是的,如果我们放弃ArrayTobObjectConverter
而使用自定义JsonConverter,我们可以处理这两种格式。这也将使我们能够简化模型,并摆脱字典
。我已经更新了我的答案。做得好,非常有帮助!了解了很多关于自定义json解析的知识!谢克诺问题;很高兴我能帮忙!
var root = JsonConvert.DeserializeObject<RootObject>(json);
Console.WriteLine("Root version: " + root.Version);
Console.WriteLine("Versioned files:");
foreach (var vf in root.VersionedFiles)
{
Console.WriteLine(" Key: " + vf.Key);
Console.WriteLine(" Label: " + (vf.Label ?? "(none)"));
Console.WriteLine(" Items:");
foreach (var item in vf.Items)
{
Console.WriteLine(" Version: " + item.Version);
Console.WriteLine(" Fields:");
foreach (var field in item.Fields)
{
Console.WriteLine(" Field name: " + field.Name);
Console.WriteLine(" Field type: " + field.Type);
Console.WriteLine();
}
}
}