AD8
AD8

Reputation: 2208

JSON to object C# (mapping complex API response to C# object)

I am able to handle simple JSON serialization and deserialization but this API response seems little complicated, and I am seeking an advice as to what would be ideal approach to tackle this.

I'm trying to call an API for MVC application. Goal is to map API data to model. API endpoint is https://www.alphavantage.co/query?function=TIME_SERIES_INTRADAY&symbol=MSFT&interval=1min&apikey=MyAPIKey

Troubles here are:

  1. JSON data keys have white space in them.
  2. When I tried doing paste special in Visual studio, It gave me a long list of classes for each date entry separately, because this API call returns a separate set of information for date.

To solve problem explained in point 1, I used [JsonProperty("1. Information")] in class. And in my code..

        public async Task TSI()
        {
            HttpClient client = new HttpClient();
            //Uri uri = new Uri("http://date.jsontest.com/");
            Uri uri = new Uri("https://www.alphavantage.co/query?function=TIME_SERIES_INTRADAY&symbol=MSFT&interval=5min&apikey=demo");
            client.DefaultRequestHeaders.Accept.Clear();
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

            HttpResponseMessage response = await client.GetAsync(uri);
            if (response.IsSuccessStatusCode)
            {
                dynamic result = await response.Content.ReadAsAsync<object>();

                IEnumerable<dynamic> dObj = JsonConvert.DeserializeObject<dynamic>(result.ToString());

                IEnumerable<dynamic> t1 = dObj.FirstOrDefault();
                IEnumerable<dynamic> t2 = dObj.LastOrDefault();
                dynamic MetaData = t1.FirstOrDefault();

                Rootobject ro = new Rootobject();
                ro.MetaData = MetaData;

            }

PS: I'm relatively new to make API calls and handling them.

I was able to make a call to

date.jsontest.com

and map the API data to model (which I had created using paste special)

//API response
    {
        "time": "12:53:22 PM",
        "milliseconds_since_epoch": 1504875202754,
        "date": "09-08-2017"
    }

//C# code to map to API data
    public class sampleObject
    {
        public string time { get; set; }
        public long milliseconds_since_epoch { get; set; }
        public string date { get; set; }
    }

My RootObject looks like this:

public class Rootobject
    {
        [JsonProperty("Meta Data")]
        public MetaData MetaData { get; set; }

        [JsonProperty("Time Series (1min)")]
        public TimeSeries1Min TimeSeries1min { get; set; }
    }

    public class MetaData
    {
        [JsonProperty("1. Information")]
        public string _1Information { get; set; }

        [JsonProperty("2. Symbol")]
        public string _2Symbol { get; set; }

        [JsonProperty("3. Last Refreshed")]
        public string _3LastRefreshed { get; set; }

        [JsonProperty("4. Interval")]
        public string _4Interval { get; set; }

        [JsonProperty("5. Output Size")]
        public string _5OutputSize { get; set; }

        [JsonProperty("6. Time Zone")]
        public string _6TimeZone { get; set; }
    }

// I have so many of these sub-classes for dates, which again is an issue
    public class TimeSeries1Min
    {
            public _20170907160000 _20170907160000 { get; set; }
            public _20170907155900 _20170907155900 { get; set; }
....
....}



public class _20170907160000
    {
        public string _1open { get; set; }
        public string _2high { get; set; }
        public string _3low { get; set; }
        public string _4close { get; set; }
        public string _5volume { get; set; }
    }

    public class _20170907155900
    {
        public string _1open { get; set; }
        public string _2high { get; set; }
        public string _3low { get; set; }
        public string _4close { get; set; }
        public string _5volume { get; set; }
    }

Upvotes: 1

Views: 9595

Answers (2)

L.B
L.B

Reputation: 116108

It is hard to create a model from this json, but you can convert those data to dictionary

var jObj = JObject.Parse(json);
var metadata = jObj["Meta Data"].ToObject<Dictionary<string, string>>();
var timeseries = jObj["Time Series (1min)"].ToObject<Dictionary<string, Dictionary<string, string>>>();

Upvotes: 6

ObiEff
ObiEff

Reputation: 650

The following code should do what you want

       if (response.IsSuccessStatusCode)
        {
            var result = await response.Content.ReadAsStringAsync();

            var obj = JsonConvert.DeserializeObject<Rootobject>(result);
            //No idea what you want to do with this line as there is no MetaData property on the root object
            obj.MetaData = MetaData;

        }

Upvotes: 1

Related Questions