0

I have a JSON file I am trying to deserialize, but there is a tag inside the items array that's changing, so how can this be specified in the class description, see class description I have now below.

When I deserialize, I get this message: Error in GetRapidAPIDataForSymbols:Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[MarketDataProvider.YahooHistory+RapidAPIItem]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.

The JSON:

{
    "meta": {
        "currency": "EUR",
        "symbol": "UZU.DE",
        "exchangeName": "GER",
        "instrumentType": "EQUITY",
        "firstTradeDate": 911462400,
        "regularMarketTime": 1604397503,
        "gmtoffset": 3600,
        "timezone": "CET",
        "exchangeTimezoneName": "Europe/Berlin",
        "regularMarketPrice": 50.2,
        "chartPreviousClose": 51,
        "priceHint": 2,
        "dataGranularity": "1d",
        "range": ""
    },
    "items": {
        "1340002800": {
            "date": "18-06-2012",
            "open": 19.05,
            "high": 19.05,
            "low": 19.05,
            "close": 19.05,
            "adjclose": 16.09
        },
        "1340089200": {
            "date": "19-06-2012",
            "open": 19.04,
            "high": 19.05,
            "low": 19.04,
            "close": 19.04,
            "adjclose": 16.09
        },
        "1340175600": {
            "date": "20-06-2012",
            "open": 19.04,
            "high": 19.04,
            "low": 19.04,
            "close": 19.04,
            "adjclose": 16.09
        },
        "1340262000": {
            "date": "21-06-2012",
            "open": 19.05,
            "high": 19.05,
            "low": 19.05,
            "close": 19.05,
            "adjclose": 16.09
        },
        "1604397503": {
            "date": "03-11-2020",
            "open": 50.6,
            "high": 50.6,
            "low": 50.2,
            "close": 50.2,
            "adjclose": 50.2
        }
    },
    "error": null
}
My classes:


public class Meta
{
    public string currency { get; set; }
    public string symbol { get; set; }
    public string exchangeName { get; set; }
    public string instrumentType { get; set; }
    public long? firstTradeDate { get; set; }
    public long? regularMarketTime { get; set; }
    public int? gmtoffset { get; set; }
    public string timezone { get; set; }
    public string exchangeTimezoneName { get; set; }
    public decimal? regularMarketPrice { get; set; }
    public decimal? chartPreviousClose { get; set; }
    public decimal? previousClose { get; set; }
    public int? scale { get; set; }
    public int? priceHint { get; set; }
    public string dataGranularity { get; set; }
    public string range { get; set; }
}

public class RapidAPIHistoryResponse
{
    [XmlElement("meta")]
    public Meta meta { get; set; }
    [XmlElement("items")]
    public List<RapidAPIItem> items { get; set; }
    public object error { get; set; }
}
public class RapidAPIItem
{
    string dateTag { get; set; }
    public YahooPrice item { get; set; }
}


My code:
var client = new RestClient("https://yahoo-finance15.p.rapidapi.com/api/yahoo/hi/history/UZU.DE/1d);
                var request = new RestRequest(Method.GET);
                request.AddHeader("x-rapidapi-host", "yahoo-finance15.p.rapidapi.com");
                request.AddHeader("x-rapidapi-key", StartParameters.RapidAPIKey);
                IRestResponse response = client.Execute(request);
                YahooHistory.RapidAPIHistoryResponse history = JsonConvert.DeserializeObject<YahooHistory.RapidAPIHistoryResponse>(response.Content);
  • 2
    You can use a `Dictionary` for `items` as shown in [How can I parse a JSON string that would cause illegal C# identifiers?](https://stackoverflow.com/a/24536564/3744182) or [Create a strongly typed c# object from json object with ID as the name](https://stackoverflow.com/a/34213724/3744182) or [Parsing JSON Object with variable properties into strongly typed object](https://stackoverflow.com/q/34202496/3744182). (You don't show `YahooPrice` but I assume it has properties `date`, `open`, `high`, `low`, `close` and `adjclose`.) In fact I think this is a duplicate, agree? – dbc Nov 03 '20 at 15:08
  • Yes, the good old Dictionary did the job, thank you! My class ended up like this: public class RapidAPIHistoryResponse { [XmlElement("meta")] public Meta meta { get; set; } [XmlElement("items")] //public Items items { get; set; } public Dictionary items { get; set; } public object error { get; set; } } – Magne Brenås Nov 03 '20 at 20:27

2 Answers2

0

As long as you honor the key to the Dictionary of Items:

public Dictionary<string, Item> Items { get; set; }

In the example:

 "items": {
    "1340002800": {
        //...
    },
    "1340089200": {
      //...
    },

1340002800, and 1340089200 are keys for a Dictionary of a C# type that looks like:

Dictionary<string, T> myDictionary  

So you need the key to be a string, and then the custom object.

This will also let you do things with each item in the "list":

var myResult = yahooQuotes.Items.Where(w => w.Item.High - w.Item.Low > 5).Select(s => s.Key);
Austin T French
  • 5,022
  • 1
  • 22
  • 40
-1

In your Json you have "items": {....} With the "{}" You say that items is an object. But you want "items" to be an arrary "[]". So you Json should be more like

"items" : [{"1604397503": {
        "date": "03-11-2020",
        "open": 50.6,
        "high": 50.6,
        "low": 50.2,
        "close": 50.2,
        "adjclose": 50.2
    }},{"1340262000": {
        "date": "21-06-2012",
        "open": 19.05,
        "high": 19.05,
        "low": 19.05,
        "close": 19.05,
        "adjclose": 16.09
    },

}]

H. Hakvoort
  • 161
  • 1
  • 2
  • 14
  • I somehow doubt the OP can re-write Yahoo's stock API to fit his whim... – Austin T French Nov 03 '20 at 15:15
  • Also, this won't work because, in the JSON you propose, the property names `"1604397503"` are still variable, necessitating the use of a dictionary. OP's data model needs fixed property names `{"dateTag": "1340262000", "item" : { /* ... */ } }` – dbc Nov 03 '20 at 15:25