0

I am building an MVC app and I am pulling data from an API. However, when I run the app, I get the error below. If I remove the line of code causing the error, then the app runs fine but no data is returned.

Below is the link to the error message screenshot

    public List<DailyEquity> GetDailyChart(string symbol)
    {
        // string to specify information to be retrieved from the API
        string IEXTrading_API_PATH = BASE_URL + "stock/" + symbol + "/chart/1d";

        // initialize objects needed to gather data
        string Dailycharts = "";
        List<DailyEquity> DailyEquities = new List<DailyEquity>();
        httpClient.BaseAddress = new Uri(IEXTrading_API_PATH);

        // connect to the API and obtain the response
        HttpResponseMessage response = httpClient.GetAsync(IEXTrading_API_PATH).GetAwaiter().GetResult();

        // now, obtain the Json objects in the response as a string
        if (response.IsSuccessStatusCode)
        {
            Dailycharts = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
            var aa = Dailycharts.GetType();
        }

        // parse the string into appropriate objects
        if (!Dailycharts.Equals(""))
        {
            DailyChartRoot dailyroot = JsonConvert.DeserializeObject<DailyChartRoot>(Dailycharts,
            new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
            DailyEquities = dailyroot.dailychart.ToList();
        }

        // fix the relations. By default the quotes do not have the company symbol
        //  this symbol serves as the foreign key in the database and connects the quote to the company
        foreach (DailyEquity Equity in DailyEquities)
        {
            Equity.symbol = symbol;
        }

        return DailyEquities;
    }

But an error is thrown at:

 // parse the string into appropriate objects
        if (!Dailycharts.Equals(""))
        {
            DailyChartRoot dailyroot = JsonConvert.DeserializeObject<DailyChartRoot>(Dailycharts,
            new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
            DailyEquities = dailyroot.dailychart.ToList();
        }

"Newtonsoft.Json.JsonSerializationException: 'Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'API_Usage.Models.DailyChartRoot' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly. To fix this error either change the JSON to a JSON object (e.g. {"name":"value"}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array. Path '', line 1, position 1.'"

This is the Model class from the Model folder.

public class DailyChartRoot
  {
    public DailyEquity[] dailychart { get; set; }
  }

public class DailyEquity
{
    public int DailyEquityId { get; set; }
    public string minute { get; set; }
    public float marketaverage { get; set; }
    public float marketnotional { get; set; }
    public float marketnumberoftrades { get; set; }
    public float marketopen { get; set; }
    public float marketclose { get; set; }
    public float markethigh { get; set; }
    public float marketlow { get; set; }
    public float marketvolume { get; set; }
    public float average { get; set; }
    public string symbol { get; set; }
}

This is a sample output from the API:

[{"date":"20190405","minute":"09:30","label":"09:30 AM","high":196.47,"low":196.14,"average":196.271,"volume":2360,"notional":463200.325,"numberOfTrades":26,"marketHigh":196.48,"marketLow":196.14,"marketAverage":196.354,"marketVolume":308339,"marketNotional":60543617.1182,"marketNumberOfTrades":712,"open":196.47,"close":196.21,"marketOpen":196.45,"marketClose":196.217,"changeOverTime":0,"marketChangeOverTime":0},{"date":"20190405","minute":"09:31","label":"09:31 AM","high":196.28,"low":196.07,"average":196.147,"volume":2148,"notional":421324.74,"numberOfTrades":25,"marketHigh":196.289,"marketLow":195.93,"marketAverage":196.113,"marketVolume":210621,"marketNotional":41305476.8289,"marketNumberOfTrades":1018,"open":196.1,"close":196.26,"marketOpen":196.22,"marketClose":196.24,"changeOverTime":-0.0006317795293242263,"marketChangeOverTime":-0.0012273750471088639}

DavidG
  • 113,891
  • 12
  • 217
  • 223
bonashhh
  • 23
  • 1
  • 5
  • 2
    Please don't post code and error messages as images, add the actual text to the question so people can search. Also, you need to provide more details, like what is the JSON being deserialised and what does `DailyChartRoot` look like. – DavidG Apr 07 '19 at 17:00
  • 1
    As an aside, this code looks really dangerous as you are calling `Task.GetAwaiter().GetResult()` instead of `await`ing it correctly. – DavidG Apr 07 '19 at 17:02
  • 1
    Your model doesn't match your json, it looks closer to deserializing as a `DailyEquity[]` not a `DailayChartRoot`. You don't have a root object just an json array. – JSteward Apr 07 '19 at 17:52

1 Answers1

0

The Exception says the object you're deserializing into does not match what your JSON contains.

Here's what the (formatted) json object looks like:

[
    {
        "date": "20190405",
        "minute": "09:30",
        "label": "09:30 AM",
        "high": 196.47,
        "low": 196.14,
        "average": 196.271,
        "volume": 2360,
        "notional": 463200.325,
        "numberOfTrades": 26,
        "marketHigh": 196.48,
        "marketLow": 196.14,
        "marketAverage": 196.354,
        "marketVolume": 308339,
        "marketNotional": 60543617.1182,
        "marketNumberOfTrades": 712,
        "open": 196.47,
        "close": 196.21,
        "marketOpen": 196.45,
        "marketClose": 196.217,
        "changeOverTime": 0,
        "marketChangeOverTime": 0
    },
    {
        "date": "20190405",
        "minute": "09:31",
        "label": "09:31 AM",
        "high": 196.28,
        "low": 196.07,
        "average": 196.147,
        "volume": 2148,
        "notional": 421324.74,
        "numberOfTrades": 25,
        "marketHigh": 196.289,
        "marketLow": 195.93,
        "marketAverage": 196.113,
        "marketVolume": 210621,
        "marketNotional": 41305476.8289,
        "marketNumberOfTrades": 1018,
        "open": 196.1,
        "close": 196.26,
        "marketOpen": 196.22,
        "marketClose": 196.24,
        "changeOverTime": -0.0006317795293242263,
        "marketChangeOverTime": -0.0012273750471088639
    }
]

You could load the objects directly as a List, by using List<DailyEquity> as the Type for JsonConvert.DeserializeObject<T>

// Parsing directly to a List<>
List<DailyEquity> equities = JsonConvert.DeserializeObject<List<DailyEquity>>(/*put your parameters here*/);

I've setup some test cases for your scenario. The following gets me the Exception:

    public void TestJsonDeserialize()
        {
            string jsonStr = /* your json string here */;

            var jsonObj = JsonConvert.DeserializeObject<DailyEquityRoot>(jsonStr);
        }

Changing the Deserialize type to a List of DailyEquity seems to do the job on my test case:

public void TestJsonDeserialize()
        {
            string jsonStr = /* your json goes here*/;

            var jsonObj = JsonConvert.DeserializeObject<List<DailyEquity>>(jsonStr);

            // Asserting the expected result we get from Deserializing
            Assert.NotEmpty(jsonObj);       // Asserts that the collection is not empty
            Assert.Equal(2, jsonObj.Count); // Asserts that the collection size is 2            

            var dailyEquityRecord = jsonObj.First();    // Let's take a look at the first object in the list
            Assert.NotNull(dailyEquityRecord);  // Asserting that the object has been loaded
            Assert.Equal("09:30 AM", dailyEquityRecord.label);  // Asserting that the label for the first record is as expected
        }

I used the following implementation of your json's class:

public class DailyEquity
        {
            public string date { get; set; }
            public string minute { get; set; }
            public string label { get; set; }
            public float high { get; set; }
            public float low { get; set; }
            public float average { get; set; }
            public int volume { get; set; }
            public float notional { get; set; }
            public int numberOfTrades { get; set; }
            public float marketHigh { get; set; }
            public float marketLow { get; set; }
            public float marketAverage { get; set; }
            public int marketVolume { get; set; }
            public float marketNotional { get; set; }
            public int marketNumberOfTrades { get; set; }
            public float open { get; set; }
            public float close { get; set; }
            public float marketOpen { get; set; }
            public float marketClose { get; set; }
            public float changeOverTime { get; set; }
            public float marketChangeOverTime { get; set; }
        }
Alves RC
  • 1,778
  • 14
  • 26
  • Thanks. But when I run the app now, no data is getting displayed. – bonashhh Apr 07 '19 at 19:45
  • Could you place a breakpoint on the `JsonConvert` line and check what values are stored in the `Dailycharts` and `dailyEquities ` variables? – Alves RC Apr 07 '19 at 19:54
  • Dailycharts has values "[{\"date\":\"20190405\",\"minute\":\"09:30\",\"label\":\"09:30 AM\",... whereas dailyEquities has null – bonashhh Apr 07 '19 at 19:59
  • I'll setup a test case using your same scenario, was away from my pc these last days. I'll update my answer as soon as I'm able to replicate – Alves RC Apr 09 '19 at 13:57