0

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?

7
  • 1
    Declare classes to hold your properties, then deserialize into those. Your question isn't clear, can you show us what you tried? Commented Mar 22, 2019 at 11:05
  • You will need a custom deserializer most likely, or you'll end up with objects/dynamic types, due to the fact that you have an array containing 1 object and then 1 array, so you can't create List<T>, here because you have different T's for different elements. Commented Mar 22, 2019 at 11:07
  • 1
    Possible duplicate of Deserialize array of key value pairs using Json.NET Commented Mar 22, 2019 at 11:08
  • If working only with one object ts+id+val, I can use: Commented Mar 22, 2019 at 11:12
  • You can use JsonConvert.DeserializeObject<JToken>(json).Select(token => token is JArray ? (object)token.ToObject<List<Other>>() : (object)token.ToObject<TokenData>()), replace with the right types. Commented Mar 22, 2019 at 11:14

2 Answers 2

2

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Your answer completely solves my problem. Thank you :)
0

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

2 Comments

Thank you for the answer, but I'm afraid I am not able to use the resulting vars. Queries are new to me and I don't know, how to print the data contained in tokens and innerData. I would appreciate your help.
you could print linq results as was mentioned before. I added it to post answer

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.