首页 > 解决方案 > 如何在 C# 中将 JSON 转换为 Datatable(JSON 包含一个数组列空值和子文档值)

问题描述

Github API 将 json 转换为数据表。以下是示例 json 数据:

[
  {
    "id": 132,
    "description": "",
    "name": "project",
    "name_with_namespace": "Source Admin / project",
    "path": "project",
    "path_with_namespace": "root/project",
    "created_at": "2019-01-18T08:10:17.594Z",
    "default_branch": "master",
    "tag_list": [],
    "ssh_url_to_repo": "git@codecommit.company.com:root/project.git",
    "http_url_to_repo": "http://codecommit.companyname.com/root/project.git",
    "web_url": "http://codecommit.companyname.com/root/project",
    "readme_url": null,
    "avatar_url": null,
    "star_count": 0,
    "forks_count": 0,
    "last_activity_at": "2019-04-10T06:59:10.992Z",
    "namespace": {
      "id": 1,
      "name": "root",
      "path": "root",
      "kind": "user",
      "full_path": "root",
      "parent_id": null
    }
  },
  {
    "id": 131,
    "description": "",
    "name": "project1",
    "name_with_namespace": "Source Admin / project1",
    "path": "project1",
    "path_with_namespace": "root/project1",
    "created_at": "2019-01-18T08:10:01.909Z",
    "default_branch": "master",
    "tag_list": [],
    "ssh_url_to_repo": "git@codecommit.company.com:root/project1.git",
    "http_url_to_repo": "http://codecommit.company.com/root/project1.git",
    "web_url": "http://codecommit.company.com/root/project1",
    "readme_url": null,
    "avatar_url": null,
    "star_count": 0,
    "forks_count": 0,
    "last_activity_at": "2019-05-29T08:44:03.145Z",
    "namespace": {
      "id": 1,
      "name": "root",
      "path": "root",
      "kind": "user",
      "full_path": "root",
      "parent_id": null
    }
  }
]

转换时出现两个问题:

var json1 = JsonConvert.DeserializeObject<DataTable>(json);

1)由于空数组字段:"tag_list":[]

错误:读取 DataTable 时出现意外的 JSON 令牌:EndArray。路径“[0].tag_list”,第 1 行,位置 280。

2)由于子文档:namespace

{"id":1,"name":"root","path":"root","kind":"user","full_path":"root","parent_id":null}

错误:读取 DataTable 时出现意外的 JSON 令牌:StartObject。路径“[0].namespace”,第 1 行,位置 555。

我不想要所有列值,只有三个列值:

"id":132,"name":"project",created_at":"2019-01-18T08:10:17.594Z".

标签: c#jsonjson.net

解决方案


因为您有一个复杂的对象(意思是嵌套类),所以您将无法将其反序列化为数据表。一个数据表只能表示一个平面的一维数据集。它不能保存一组也包含子集的数据。

因此,您要做的是将其反序列化为一个对象。我拿了你的 json,并使用这个网站(http://json2csharp.com)将它转换成一个类:

public class MyObject
{
    public int id { get; set; }
    public string description { get; set; }
    public string name { get; set; }
    public string name_with_namespace { get; set; }
    public string path { get; set; }
    public string path_with_namespace { get; set; }
    public DateTime created_at { get; set; }
    public string default_branch { get; set; }
    public List<object> tag_list { get; set; }
    public string ssh_url_to_repo { get; set; }
    public string http_url_to_repo { get; set; }
    public string web_url { get; set; }
    public object readme_url { get; set; }
    public object avatar_url { get; set; }
    public int star_count { get; set; }
    public int forks_count { get; set; }
    public DateTime last_activity_at { get; set; }
    public Namespace @namespace { get; set; }
}

public class Namespace
{
    public int id { get; set; }
    public string name { get; set; }
    public string path { get; set; }
    public string kind { get; set; }
    public string full_path { get; set; }
    public object parent_id { get; set; }
}

现在,您可以这样做:

var json1 = JsonConvert.DeserializeObject<MyObject>(json);

然后json1将是从您的 json 创建的对象。从那里,您可以轻而易举地获得所需的值。

编辑:

我刚刚意识到您的 json 是一个列表,而不是单个项目,所以它将是:

var json1 = JsonConvert.DeserializeObject<List<MyObject>>(json);

推荐阅读