0

I'm trying to deserialize and string with unknown keys and based on the examples I've seen using a dictionary seems to be the best way, however ever when I use a dictionary, my json deserialization returns null.

Here is my class I am trying to deserialize to:

namespace TDAPI.Model.Qoutes
{
    public class Rootobject
    {
        public Dictionary<string, Equity> Equity { get; set; }
    }

    public class Equity
    {
        public string assetType { get; set; }
        public string assetMainType { get; set; }
        public string cusip { get; set; }
        public string symbol { get; set; }
        public string description { get; set; }
        public float bidPrice { get; set; }
        public int bidSize { get; set; }
        public string bidId { get; set; }
        public float askPrice { get; set; }
        public int askSize { get; set; }
        public string askId { get; set; }
        public float lastPrice { get; set; }
        public int lastSize { get; set; }
        public string lastId { get; set; }
        public float openPrice { get; set; }
        public float highPrice { get; set; }
        public float lowPrice { get; set; }
        public string bidTick { get; set; }
        public float closePrice { get; set; }
        public float netChange { get; set; }
        public int totalVolume { get; set; }
        public long quoteTimeInLong { get; set; }
        public long tradeTimeInLong { get; set; }
        public float mark { get; set; }
        public string exchange { get; set; }
        public string exchangeName { get; set; }
        public bool marginable { get; set; }
        public bool shortable { get; set; }
        public float volatility { get; set; }
        public int digits { get; set; }
        public float _52WkHigh { get; set; }
        public float _52WkLow { get; set; }
        public float nAV { get; set; }
        public float peRatio { get; set; }
        public float divAmount { get; set; }
        public float divYield { get; set; }
        public string divDate { get; set; }
        public string securityStatus { get; set; }
        public float regularMarketLastPrice { get; set; }
        public int regularMarketLastSize { get; set; }
        public float regularMarketNetChange { get; set; }
        public long regularMarketTradeTimeInLong { get; set; }
        public float netPercentChangeInDouble { get; set; }
        public float markChangeInDouble { get; set; }
        public float markPercentChangeInDouble { get; set; }
        public float regularMarketPercentChangeInDouble { get; set; }
        public bool delayed { get; set; }
        public bool realtimeEntitled { get; set; }
    }
}

Here is the string (quote) I am trying to deserialize:

{
  "AMD": {
    "assetType": "EQUITY",
    "assetMainType": "EQUITY",
    "cusip": "007903107",
    "symbol": "AMD",
    "description": "Advanced Micro Devices, Inc. - Common Stock",
    "bidPrice": 90.85,
    "bidSize": 100,
    "bidId": "Q",
    "askPrice": 90.9,
    "askSize": 1000,
    "askId": "P",
    "lastPrice": 90.9,
    "lastSize": 0,
    "lastId": "P",
    "openPrice": 90.04,
    "highPrice": 91.26,
    "lowPrice": 88.53,
    "bidTick": " ",
    "closePrice": 90.9,
    "netChange": 0,
    "totalVolume": 35278416,
    "quoteTimeInLong": 1625875188410,
    "tradeTimeInLong": 1625875174724,
    "mark": 90.9,
    "exchange": "q",
    "exchangeName": "NASD",
    "marginable": true,
    "shortable": true,
    "volatility": 0.011,
    "digits": 4,
    "52WkHigh": 99.23,
    "52WkLow": 52.26,
    "nAV": 0,
    "peRatio": 38.5864,
    "divAmount": 0,
    "divYield": 0,
    "divDate": "",
    "securityStatus": "Normal",
    "regularMarketLastPrice": 90.9,
    "regularMarketLastSize": 12129,
    "regularMarketNetChange": 0,
    "regularMarketTradeTimeInLong": 1625860800755,
    "netPercentChangeInDouble": 0,
    "markChangeInDouble": 0,
    "markPercentChangeInDouble": 0,
    "regularMarketPercentChangeInDouble": 0,
    "delayed": false,
    "realtimeEntitled": true
  },
  "ROKU": {
    "assetType": "EQUITY",
    "assetMainType": "EQUITY",
    "cusip": "77543R102",
    "symbol": "ROKU",
    "description": "Roku, Inc. - Class A Common Stock",
    "bidPrice": 431.3,
    "bidSize": 100,
    "bidId": "P",
    "askPrice": 431.94,
    "askSize": 100,
    "askId": "P",
    "lastPrice": 431.3,
    "lastSize": 0,
    "lastId": "D",
    "openPrice": 420.01,
    "highPrice": 433.715,
    "lowPrice": 412.51,
    "bidTick": " ",
    "closePrice": 431.61,
    "netChange": -0.31,
    "totalVolume": 3141742,
    "quoteTimeInLong": 1625875030834,
    "tradeTimeInLong": 1625875192528,
    "mark": 431.61,
    "exchange": "q",
    "exchangeName": "NASD",
    "marginable": true,
    "shortable": true,
    "volatility": 0.0446,
    "digits": 4,
    "52WkHigh": 486.72,
    "52WkLow": 136.28,
    "nAV": 0,
    "peRatio": 529.6933,
    "divAmount": 0,
    "divYield": 0,
    "divDate": "",
    "securityStatus": "Normal",
    "regularMarketLastPrice": 431.61,
    "regularMarketLastSize": 501,
    "regularMarketNetChange": 0,
    "regularMarketTradeTimeInLong": 1625860800927,
    "netPercentChangeInDouble": -0.0718,
    "markChangeInDouble": 0,
    "markPercentChangeInDouble": 0,
    "regularMarketPercentChangeInDouble": 0,
    "delayed": false,
    "realtimeEntitled": true
  }
}

Here is how I am calling the deserialization:

var obj = JsonConvert.DeserializeObject<TDAPI.Model.Qoutes.Rootobject>(qoute);

Any help is appreciated

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
  • 3
    Please don't violate C# naming conventions just to get your properties and your JSON to line up; all the popular json libs support attributes to map the Json name to the c# name e.g. `[JsonProperty("something")]public int OtherThing{ get; set; }` – Caius Jard Jul 11 '21 at 20:14
  • I have no control over the data I receive (the string), this is not my data. And I never know which objects will come back. @CaiusJard. Unless i cleary don't understand your point, which is possible. The only thing I changed is AMD to Equity as the class name – user1257758 Jul 11 '21 at 20:19
  • He is saying that, for example, the property `assetType` violates the [naming conventions](https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/coding-style/coding-conventions). It should be `AssetType` and there should be an attribute on it detailed what JSON property should be filling it. – fredrik Jul 11 '21 at 20:40
  • 5
    And the problem is that you are encapsulating the Dictionary in a class which has no equivalent in your json schema. Just deserialise directly to a Dictionary. – fredrik Jul 11 '21 at 20:41
  • @fredrik Okay, I understand all that, but I didn't make this class or the string that comes back. It's an edit => paste special json in visual studio. I am just dealing with the hand I am delt. So you mean just do a public Dictionary Equity { get; set; }, I am totally lost here. – user1257758 Jul 11 '21 at 21:51
  • 1
    What he is saying is use https://quicktype.io/csharp . Look at the generated output. See all of those `JsonProperty`? That is what you should do. Or, in future, just use the link I provided. Also remove `Rootobject` - you don't need it. You need `JsonConvert.DeserializeObject(qoute)`. – mjwills Jul 11 '21 at 21:56
  • I tried public Dictionary Equity { get; set; } that returns null – user1257758 Jul 11 '21 at 21:57
  • @mjwills I didn't create the structure, or the keys, or the class, I am dealing with what they return. All I want to do deserialize this. – user1257758 Jul 11 '21 at 22:01
  • @mjwills thank you, if you set it as the answer i will mark it – user1257758 Jul 11 '21 at 22:03
  • 1
    @user1257758 - *Deserialize to `Dictionary`* was what was recommended in your [earlier question](https://stackoverflow.com/q/68324472/3744182) which was closed as a duplicate. You chose the name `Equity` instead of `Asset` which is fine, but why did you add the additional `Rootobject`? That's what caused the problem here. – dbc Jul 11 '21 at 23:05
  • You will need to use `JsonPropertyAttribute` for properties that are not valid c# identifiers. E.g. `[JsonProperty("52WkHigh")] public decimal FiftyTwoWeekHigh { get; set; }`. This case is also covered in one of the answers to [How can I parse a JSON string that would cause illegal C# identifiers?](https://stackoverflow.com/a/24536739/3744182). – dbc Jul 11 '21 at 23:09

0 Answers0