trapper66
trapper66

Reputation: 21

C# Json.Net - How to deserialize an array of objects containing an array of other objects

The Json data received from the http server is like this:

[
   {
      "token":"NlhYnzF0xqG"
   },
   [
      {
         "ts":"2019-03-21 14:06:22.123",
         "id":"CC_RTC_Second",
         "val":"22"
      },
      {
         "ts":"2019-03-21 14:06:00.096",
         "id":"CC_RTC_Minute",
         "val":"6"
      },
      {
         "ts":"2019-03-21 14:00:00.276",
         "id":"CC_RTC_Hour",
         "val":"14"
      }
   ]
]

I have tried some techniques presented in Newtonsoft.Json documentation, but I could not find the correct way. I spent two days by testing the solutions from StackOverflow answers, but with no success.

What C# types and techniques should I use in this particular case?

Data structure can vary:
complete list of attributes is: td, id, val, flags, type, uts, nr.
All of them are strings.
Server can omit the attrs if they do not exist, so for example I can obtain only ts + id.
Is there any way how to work with such a data?

Upvotes: 0

Views: 1266

Answers (2)

Oleg Bondarenko
Oleg Bondarenko

Reputation: 1820

There is my version of answer:

var strData = @"[{
         'token': 'NlhYnzF0xqG'
       },
       [{
         'ts': '2019-03-21 14:06:22.123',
         'id': 'CC_RTC_Second',
         'val': '22'
       }, {
         'ts': '2019-03-21 14:06:00.096',
         'id': 'CC_RTC_Minute',

       }, {

         'id': 'CC_RTC_Hour',
         'val': '14'
       }]
     ]";   
        var result = JsonConvert.DeserializeObject<List<JToken>>(strData);
        var tokens = result.Where( x=> x.Type == JTokenType.Object).Select(x=> x.ToObject<Token>());
        var innerData = result.Where(x => x.Type == JTokenType.Array).Select(x => x.ToObject<List<InnerData>>());

there are classes:

 public class Token
        {
             public string token { set; get; }
        }
    public class InnerData
        {
            public string ts { set; get; }
            public string id { set; get; }
            public string val { set; get; }    
        }

You could print results as was mention before :

foreach (var token in tokens)
{
    Console.WriteLine("ts: " + token.token);
}

Upvotes: 0

er-sho
er-sho

Reputation: 9771

First of all your json is quite complicated and its tedious job to create a class hierarchy for your json,

But one simple approach is that if you parse your JSON to JArray and then takes

  • 0th element to one class
  • And all remaining into list of another class

Then might be you can retrieve all your json data

string json = File.ReadAllText(@"Path to your json");

JArray jArray = JArray.Parse(json);

Token token = jArray[0].ToObject<Token>();
jArray.RemoveAt(0);
RandomData[] tokenData = jArray.First.ToObject<RandomData[]>();

//--------------------Print Data to Console-------------------

Console.WriteLine(token.token + "\n");

foreach (var item in tokenData)
{
    Console.WriteLine("ts: " + item.ts);
    Console.WriteLine("id: " + item.id);
    Console.WriteLine("val: " + item.val + "\n");
}

Console.ReadLine();

And classes are,

class Token
{
    public string token { get; set; }
}

class RandomData
{
    public string ts { get; set; }
    public string td { get; set; }
    public string id { get; set; }
    public string val { get; set; }
    public string flags { get; set; }
    public string type { get; set; }
    public string uts { get; set; }
    public string nr { get; set; }
}

Output:

enter image description here

Note: You need to install NewtonSoft NuGet package and import using Newtonsoft.Json.Linq; namespace to your program.

Upvotes: 2

Related Questions