skip to Main Content

I am dealing with a Json object with an a priori partly unknown structure. I am not sure whether I can use the deserialising object method, because I cannot predict the exact structure length and naming I wish to target.

I simply know that the structure skeleton (looking at the Json previewer) is going to be like:

[JSON]
    [meta] 
        metaname1: metavalue1
        ...
        metanameN: metavalueN
    [target]
        [0]
            targetname1: targetvalue1
            ...
            targetnameP: targetvalueP

The actual extracted structure is as follows:

{[meta, {
  "limit": 100,
  "offset": 0,
  "count": 1,
  "total": 1
}]}
{[target, [
  {
    "open": 173.99,
    "high": 175.46,
    "low": 172.675,
    "last": 175.38,
    "close": 173.66,
    "volume": 607334.0,
    "date": "2023-10-05T21:00:00+02:00",
    "symbol": "AAPL",
    "exchange": "IEXG"
  }
]]}

I would like to skip the ‘meta’ node and focus on the ‘target’ node and push the series of keys and values (targetname1, targetvalue1),…, (targetnameP, targetvalueP) into a dictionary. I have loaded the Json object using Newtonsoft.Json library after reading the data from internet at a given ‘address’.

using (HttpClient client = new HttpClient())
{
    Task<HttpResponseMessage> response = client.GetAsync(address);
    using (HttpResponseMessage message = response.Result)
    {
        using (HttpContent content = message.Content)
        {
            string jsonData = content.ReadAsStringAsync().Result;
            JObject jsonObj = JObject.Parse(jsonData);
        }
    }
}

I am not sure how to proceed next.


Addendum


Now I am trying this but I am still stuck.

class Program
{
    static void Main(string[] args)
    {
        string jsonData = @"
            {[meta, {
               "limit": 100,
               "offset": 0,
               "count": 1,
               "total": 1
            }]}
            {[target, [
              {
                "open": 173.99,
                "high": 175.46,
                "low": 172.675,
                "last": 175.38,
                "close": 173.66,
                "volume": 607334.0,
                "date": "2023-10-05T21:00:00+02:00",
                "symbol": "AAPL",
                "exchange": "IEXG"
              }
            ]]}";

        Dictionary<string, object> jsonDict = JsonConvert.DeserializeObject<Dictionary<string, object>>(jsonData);
        object jsonSubData = jsonDict["target"];
    }
}

I am failing to get ‘jsonSubData’ into another dictionary.


Is it an efficient solution?


I have come up with this. It seems to work. I am not sure it is the most efficient solution.

class Program
{
    static void Main(string[] args)
    {
        string jsonData = @"Same structure as before";

        JObject jsonObj = JObject.Parse(jsonData);
        JObject jsonSubObj = jsonObj["data"].Values<JObject>().First();

        Dictionary<string, string> jsonDict = new Dictionary<string, string>();
        foreach (JProperty property in jsonSubObj.Properties())
            jsonDict.Add(property.Name, property.Value.ToString());
    }
}

2

Answers


  1. In C#, you can use the Newtonsoft.Json library to parse JSON and push element names and values into a dictionary. Here’s an example:
    
    C#
    This code is AI-generated. Review and use carefully. Visit our FAQ for more information.
    
    using Newtonsoft.Json;
    using System.Collections.Generic;
    
    public class Program
    {
        public static void Main()
        {
            string json = @"{
                'Name': 'John Smith',
                'Age': 30,
                'City': 'New York'
            }";
    
            Dictionary<string, string> values = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
    
            foreach (var item in values)
            {
                System.Console.WriteLine("Key: {0}, Value: {1}", item.Key, item.Value);
            }
        }
    }
    In this code:
    
    We first define a JSON string json.
    We then use JsonConvert.DeserializeObject<Dictionary<string, string>>(json) to convert the JSON string into a dictionary.
    Finally, we print out the keys and values of the dictionary.
    Please note that you need to install the Newtonsoft.Json package. You can do this by using the NuGet package manager in Visual Studio or by running the following command in your Package Manager Console:
    
    Install-Package Newtonsoft.Json
    
    This code assumes that all values in your JSON are strings. If your JSON contains different types (e.g., numbers, booleans, nested objects), you might need to use Dictionary<string, object> or create a custom class that matches the structure of your JSON. If you have a more complex JSON structure, please provide it and I can help you parse it into a dictionary.
    
    Login or Signup to reply.
  2. I’m assuming the json root will always contain meta and target properties. If so, you can do this:

    public sealed class DataContainer
    {
        [JsonProperty("meta")]
        public Dictionary<string, object>? Meta { get; set; }
    
        [JsonProperty("target")]
        public Dictionary<string, object>[]? Data { get; set; }
    }
    

    then, you just do this :

    string json = @"{""meta"":{""limit"":100,""offset"":0,""count"":1,""total"":1},""target"":[{""open"":173.99,""high"":175.46,""low"":172.675,""last"":175.38,""close"":173.66,""volume"":607334.0,""date"":""2023-10-05T21:00:00+02:00"",""symbol"":""AAPL"",""exchange"":""IEXG""}]}";
    
    DataContainer? data = JsonConvert.DeserializeObject<DataContainer>(json);
    

    now you can access the Data property, and iterate over all its elements (objects).

    if you’re using System.Text.Json, then you just change the following :

    JsonPropertyAttribute         -> JsonPropertyNameAttribute 
    JsonConvert.DeserializeObject -> JsonSerializer.Deserialize
    

    if your json root has more keys than the example above, and you only want target, then you could omit the Meta property, then use the JsonSerializerSettings and set the MissingMemberHandling to MissingMemberHandling.Ignore, this will ensure you only deserialize whatever you provide in the DataContainer class.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search