Home > OS >  How to convert JSON string to Class with Newtonsoft while ignoring named json sub objects
How to convert JSON string to Class with Newtonsoft while ignoring named json sub objects

Time:07-15

Im not sure exactly the right phrasing to as this question but here is the problem. I'm getting data from CoinMarketCap and trying to convert its json response into a Object. My class looks like this:

namespace CryptoCharter.CoinMarketCap
{
    public class LatestQuotes
    {
        public List<LatestQuote> Data { get; set; }
    }
    public class LatestQuote
    {
        public string Name { get; set; }
        public string Symbol { get; set; }
        public string Slug { get; set; }
    }
}

With my Deserialize call looking like this:

LatestQuotes latestQuote = JsonConvert.DeserializeObject<LatestQuotes>(data);

Unfortunately the problem i have is that the json return is like this:

{
  "status": {
    "timestamp": "2022-07-14T18:52:04.589Z",
  },
  "data": {
    "BTC": {
      "name": "aozn4bq7ss",
      "symbol": "BTC",
      "slug": "7sh2jotqs8q",
    },
    "ETH": {
      "name": "4x98y18ibem",
      "symbol": "ETH",
      "slug": "nibbc2nhejg",
    }
  }
}

So my question is how do I get around the fact that data has more json in it. Is there a way to get newtonsoft to treat it as if it looks like this:

{
  "status": {
    "timestamp": "2022-07-14T18:52:04.589Z",
  },
  "data": [
      {"name": "aozn4bq7ss",
      "symbol": "BTC",
      "slug": "7sh2jotqs8q",
    },
    {
      "name": "4x98y18ibem",
      "symbol": "ETH",
      "slug": "nibbc2nhejg",
    }
  ]  
}

I'm having trouble finding a solution to this since the list of items could be any size I can't just assume BTC and ETH are always there and what others will be. Thanks in advance.

CodePudding user response:

try this

    var jsonParsed = JObject.Parse(json);

    LatestQuotes latestQuotes = new LatestQuotes { 
           Timestamp = (DateTime)jsonParsed["status"]["timestamp"] };

    if (jsonParsed["data"].Type.ToString() == "Array") 
       latestQuotes.Data = jsonParsed["data"].ToObject<List<LatestQuote>>();
        else latestQuotes.Data = ((JObject)jsonParsed["data"]).Properties()
                .Select(e => e.Value.ToObject<LatestQuote>()).ToList();

public class LatestQuotes
{
    public DateTime Timestamp { get; set; }
    public List<LatestQuote> Data { get; set; }
}

CodePudding user response:

I suggest deserialising the json to a dedicated class and then picking out what you need.

The model:

public class LatestQuotesResponseDto
{
   public Dictionary<string,LatestQuote> Data { get; set; }
}

Then:

// TODO error handling
var deserialised = JsonConvert.DeserializeObject<LatestQuotesResponseDto>(data);

var latestQuotes = new LatestQuotes
{
    Data = deserialised.Data.Select(kvp => kvp.Value).ToList();
}
  • Related