Search code examples
c#jsonjson.net

How to convert JSON to Datatable(JSON contains one array column empty value and sub document value) in C#


Github API hit json conversion to datatable. Following is the sample json data:

[
  {
    "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": "[email protected]: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": "[email protected]: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
    }
  }
]

Two problem araise while converting through:

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

1) because of empty array field: "tag_list":[]

Error: Unexpected JSON token when reading DataTable: EndArray. Path '[0].tag_list', line 1, position 280.

2) because of sub document: namespace

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

Error: Unexpected JSON token when reading DataTable: StartObject. Path '[0].namespace', line 1, position 555.

I don't want all columns values, only three column values:

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

Solution

  • Because you have a complex object (meaning, nested classes) you will not be able to Deserialize this to a data tabe. A data table can only represent a flat, one-dimensional set of data. It isn't capable of holding a set of data that also contains sub sets.

    So, what you will want to do is Deserialize this into an object. I took your json, and using this website (http://json2csharp.com) converted it into a class:

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

    Now, you can do this:

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

    And then json1 will be an object that was created from your json. And from there, it's a snap to obtain the values you need.

    EDIT:

    I just realized your json is a list, and not a single item, so it would be:

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