njdotnetdev
njdotnetdev

Reputation: 15

How to deserialize tabular JSON data into a list of class instances?

I am trying to read a JSON string into an object. My data is a bit different from those which have been answered.

Data:

{
  "rows": [
    {
      "id": 1,
      "data": [
        "First Column",
        "Second Column",
        "Third Column",
        "Fourth Column",
        "Fifth Column",
        "Sixth Column"
      ]
    },
    {
      "id": 2,
      "data": [
        "First Column",
        "Second Column",
        "Third Column",
        "Fourth Column",
        "Fifth Column",
        "Sixth Column"
      ]
    },
    {
      "id": 3,
      "data": [
        "First Column",
        "Second Column",
        "Third Column",
        "Fourth Column",
        "Fifth Column",
        "Sixth Column"
      ]
    }
  ]
}

I tried the following:

dynamic results = JsonConvert.DeserializeObject<dynamic>(jsonData);

var o = JsonConvert.DeserializeObject(jsonData, typeof(List<CommonPage>), new JsonSerializerSettings());

CommonPage is my class which has a set of properties like:

1. First Column
2. Second Column

I want deserialize into a list of objects so that I can edit the deserialized data. Seems like there is no straightforward answer.

I was thinking maybe I can get something like List<CommonPage> out of the JSON data so I will able to access data like following:

List<CommonPage>[0].FirstColumn (This is just an example: this is first row data which can be queried with LINQ using id in the data.)

Upvotes: 0

Views: 45

Answers (2)

Igor Quirino
Igor Quirino

Reputation: 1195

You have to provide a property called Rows to a new class and then instantiate as List.

You will use this new class as the type of deserialization

You can use quicktype to generate your json classes: https://app.quicktype.io?share=9B7eToMMux9sDZaYkQgs

Sample: https://dotnetfiddle.net/0SjzkT

Create model classes:

public partial class Pages
{
    public List<Page> Rows { get; set; }

    public override string ToString()
    {
        return string.Join("\r\n", this.Rows.Select(q=>q.ToString()).ToArray());
    }
}

public partial class Page
{
    public long Id { get; set; }
    public List<string> Data { get; set; }

    public override string ToString()
    {
        return "ID: " + this.Id.ToString() + " - Data: " + string.Join(", ", this.Data.Select(q=>q.ToString()).ToArray());
    }
}

Get distinct values:

public static void Main()
{
    string jsonStr = @"{'rows': [ ...";

    var ret = JsonConvert.DeserializeObject<Pages>(jsonStr) as Pages;
    Console.WriteLine(string.Join("\r\n", ret.Rows.SelectMany(q=>q.Data).Distinct().ToArray()));
}

Get all values:

public static void Main()
{
    string jsonStr = @"{'rows': [ ...";

    var ret = JsonConvert.DeserializeObject<Pages>(jsonStr) as Pages;
    Console.WriteLine(ret.ToString());
}

Output:

First Column
Second Column
Third Column
Fourth Column
Fifth Column
Sixth Column
ID: 1 - Data: First Column, Second Column, Third Column, Fourth Column, Fifth Column, Sixth Column
ID: 2 - Data: First Column, Second Column, Third Column, Fourth Column, Fifth Column, Sixth Column
ID: 3 - Data: First Column, Second Column, Third Column, Fourth Column, Fifth Column, Sixth Column

Upvotes: 1

StriplingWarrior
StriplingWarrior

Reputation: 156544

The easiest thing would probably be to deserialize to a JObject and do a manual transformation:

var o = JsonConvert.DeserializeObject<JObject>(json)["rows"].Select(r => new CommonPage
{
    FirstColumn = r["data"][0].Value<string>(),
    SecondColumn = r["data"][1].Value<string>(),
    // etc.
})
.ToList();

Upvotes: 0

Related Questions