Search code examples
c#jsonapijson-deserialization

How can I parse some JSON dynamically without knowing JSON values?


So I am using TDAmeritrade API to receive stock data with a C# Winforms program on Visual Studio. It takes the user input stock symbol and searches for the info. I am using HttpClient and Newtonsoft.Json and have been able to successfully perform the GET request and receive a JSON string back, but I do not know how to get all of the information I need out of it.

Here is the JSON: https://drive.google.com/file/d/1TpAUwjyqrHArEXGXMof_K1eQe0hFoaw5/view?usp=sharing

Above is the JSON string sent back to me then formatted. My goal is to record information for each price in "callExpDateMap.2021-02-19:11" and "callExpDateMap.2021-03-19:39". The problem is that for each different stock, the dates that show up in "callExpDateMap" are going to be different.

client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
            var response = await client.GetAsync(url);
            var info = await response.Content.ReadAsStringAsync();

            dynamic config = JsonConvert.DeserializeObject<dynamic>(info, new ExpandoObjectConverter());
            return config;

This is the code I have right now. I know the last for statement is not correct. How can I parse to the specific sections I want (callExpDateMap.expirationdate.StrikePrice) and get the information needed from each without knowing the dates and Strike prices beforehand? Is there a way to innumerate it and search through the JSON as if it were all a bunch of arrays?


Solution

  • The code below is perhaps not the most elegant nor complete, but I think it will get you going. I would start by using the JObject.Parse() from the Newtonsoft.Json.Linq namespace and take it from there.

    JObject root = JObject.Parse(info);
    string symbol = root["symbol"].ToObject<string>();
    foreach (JToken toplevel in root["callExpDateMap"].Children())
    {
        foreach (JToken nextlevel in toplevel.Children())
        {
            foreach (JToken bottomlevel in nextlevel.Children())
            {
                foreach (JToken jToken in bottomlevel.Children())
                {
                    JArray jArray = jToken as JArray;
                    foreach (var arrayElement in jArray)
                    {
                        InfoObject infoObject = arrayElement.ToObject<InfoObject>();
                        Console.WriteLine(infoObject.putCall);
                        Console.WriteLine(infoObject.exchangeName);
                        Console.WriteLine(infoObject.multiplier);
                    }
                }
            }
        }
    }
    
    public class InfoObject
    {
        public string putCall { get; set; }
        public string symbol { get; set; }
        public string description { get; set; }
        public string exchangeName { get; set; }
        // ...
        public int multiplier { get; set; }
        // ...
    }