Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 无法确定JSON数据的数据结构_C#_Json_Json.net - Fatal编程技术网

C# 无法确定JSON数据的数据结构

C# 无法确定JSON数据的数据结构,c#,json,json.net,C#,Json,Json.net,我有以下JSON文件,在解析时遇到问题 { "version": 2, "versioned_files": [ { "DB": [ "Table0", [ { "version": 0, "fields": [ {

我有以下JSON文件,在解析时遇到问题

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