0

I am downloading stock pricing data in this format:

{"Meta Data": { "1. Information": "Intraday (5min) open, high, low, close prices and volume", "2. Symbol": "IBM", "3. Last Refreshed": "2023-08-01 19:55:00", "4. Interval": "5min", "5. Output Size": "Compact", "6. Time Zone": "US/Eastern" }, "Time Series (5min)": { "2023-08-01 19:55:00": { "1. open": "142.8100", "2. high": "143.1000", "3. low": "142.8100", "4. close": "142.8100", "5. volume": "230" }, "2023-08-01 19:45:00": { "1. open": "143.0000", "2. high": "143.0000", "3. low": "143.0000", "4. close": "143.0000", "5. volume": "50" },.........................}

I want to deserialize in C#.

The structure of the Meta Data is predictable, this piece is working.

But the dates are unpredictable, I don't know the exact dates coming with the response, and each date has five underlying variables.

I can't structure the JsonProperty items with the exact dates therefore, so how can I deserialize data like this?

My attempt:

 public class json_price
{

    [JsonProperty("Meta Data")]
    public headers Headers { get; set; }

    public class headers
    {
        [JsonProperty("1. Information")]
        public string s1 { get; set; }
        [JsonProperty("2. Symbol")]
        public string s2 { get; set; }
        [JsonProperty("3. Last Refreshed")]
        public string s3 { get; set; }
        [JsonProperty("4. Interval")]
        public string s4 { get; set; }
        [JsonProperty("5. Output Size")]
        public string s5 { get; set; }
        [JsonProperty("6. Time Zone")]
        public string s6 { get; set; }
    }


    [JsonProperty("Time Series 5min")]
    public priceheader ph { get; set; }


    // [JsonProperty("??????")] unknown date so can't refer to JsonProperty??
    public class priceheader
    {
        public datepricing[] dp { get; set; }
    }
             
    public class datepricing
    {

        [JsonProperty("1. open")]
        public long O { get; set; }
        [JsonProperty("2. high")]
        public long H { get; set; }
        [JsonProperty("3. low")]
        public long L { get; set; }
        [JsonProperty("4. close")]
        public long C { get; set; }
        [JsonProperty("5. volume")]
        public long V { get; set; }

    }

}

This yields a correctly populated Headers object but an empty "ph" object when I try to deserialize:

json_price results = JsonConvert.DeserializeObject<json_price>(output);

Thanks!

DanB
  • 39
  • 6
  • 1
    Does this answer your question? [json deserialization to C# with dynamic keys](https://stackoverflow.com/questions/65727513/json-deserialization-to-c-sharp-with-dynamic-keys) – Charlieface Aug 03 '23 at 09:37
  • It may well have done it i knew to look for "dynamic keys" :) I need to upskill! – DanB Aug 04 '23 at 16:12

1 Answers1

1

Using a dictionary works if you fix the types of datepricing properties

json_price results = JsonConvert.DeserializeObject<json_price>(json);

public class json_price
{
    [JsonProperty("Meta Data")]
    public headers Headers { get; set; }

    [JsonProperty("Time Series (5min)")]
    public Dictionary<string, datepricing> ph { get; set; }
}
public class datepricing
{
    [JsonProperty("1. open")]
    public double O { get; set; }
    [JsonProperty("2. high")]
    public double H { get; set; }
    [JsonProperty("3. low")]
    public double L { get; set; }
    [JsonProperty("4. close")]
    public double C { get; set; }
    [JsonProperty("5. volume")]
    public long V { get; set; }
}

but I don't like a DateTime property as a Dictionary key and prefer using a List

    var jObj=JObject.Parse(json);
    
    json_price results = jObj.ToObject<json_price>();
    
    foreach (JProperty prop in ((JObject) jObj["Time Series (5min)"]).Properties())
    {
        var dp=prop.Value.ToObject<datepricing>();
        dp.pricingDate= DateTime.Parse(prop.Name);
        results.ph.Add(dp);
    }

public class json_price
{
    [JsonProperty("Meta Data")]
    public headers Headers { get; set; }

    public List<datepricing> ph { get; set; } = new();
}

public class datepricing
{
    public DateTime pricingDate { get; set; }

    // another properties
}
Serge
  • 40,935
  • 4
  • 18
  • 45
  • Thanks very much for the response Serge. – DanB Aug 03 '23 at 08:53
  • Thanks very much for the response Serge. The first solution above doesn't seem to work for me - I get an error converting to Int64 (FormatException: Input string was not in a correct format.) The data point being converted is "144.3000". The second solution I have been playing with but it doesn't like the ph...=new();, not sure if you have any ideas here? – DanB Aug 03 '23 at 12:06
  • @DanB Pls read carefully my answer. You have to fix a datepricing class, replace long witrh double. – Serge Aug 03 '23 at 12:34
  • I did make this change, but it is one of the doubles (the first opening price) which is failing - not the volume / double number. However - you are correct it is a data type issue, and having changed all the types to string, this now works But if I do want the longs/doubles rather than a string for these price/volume fields, how can I parse them as numbers when creating the dictionary entry? – DanB Aug 03 '23 at 17:00
  • @DanB I don't know what are you talking about. All my code is tested and working properly with a json you posted. You must be trying a different json. You have to put a real json in order I could suggest something else. – Serge Aug 03 '23 at 17:11
  • You're the expert :) it is working now as strings - my question is how would I parse strings into ints/doubles now when creating that dictionary? – DanB Aug 03 '23 at 17:27
  • @DanB It is working ints and doubles too, I don't know why it is not working for you – Serge Aug 03 '23 at 17:32
  • Well just hypothetically, how would you parse raw strings into doubles when creating a dictionary, as that will solve my problem also? – DanB Aug 03 '23 at 17:48
  • Also, this line in the second piece of your code yields an error - "new" cannot be used with Tuples? public List ph { get; set; } = new (); – DanB Aug 03 '23 at 18:43
  • GOT IT! :) It works perfectly thank you Serge, i just needed to instantiate the List ph properly as it wasn't liking new() Thanks for your help! – DanB Aug 03 '23 at 18:52