0

I'm trying to get Top 5 most profitable coins for mining from WhatToMine using their JSON in my pet C# project.

The problem is that instead of an array this site returns just single object (I've sorted the list of properties for brevity):

{
   "coins":
   {
      "Hush":
      {
         "id":168,
         "tag":"HUSH",
         "algorithm":"Equihash",
      },
      "Zclassic":
      {
         "id":167,
         "tag":"ZCL",
         "algorithm":"Equihash"
      }
}

I don't really need coin name, as tag is sufficient, so I would like to have something like this:

[
   {
      "id":168,
      "tag":"HUSH",
      "algorithm":"Equihash",
   },
   {
      "id":167,
      "tag":"ZCL",
      "algorithm":"Equihash"
   }
]

I tried to use JSON2CSharp, but it generated a bunch of classes with the same properties one per each coin. And because new ones are constantly added I don't want to change my code every time.

Surely I can do some search/replace or regex to make the JSON response string look like I need, but I guess true developers (which I'm not part of) know a better and more elegant way of deserializing a single object into list/array.

Palle Due
  • 5,929
  • 4
  • 17
  • 32
Sergey Sypalo
  • 1,223
  • 5
  • 16
  • 35
  • 1
    One of the answers here will work: https://stackoverflow.com/questions/4535840/deserialize-json-object-into-dynamic-object-using-json-net – rene Dec 24 '17 at 21:46
  • 1
    The class name doesnt matter so you could use something like `CoinItem` defined as `{id, tag, algo}` and map any/all types to it (`CoinItem Hush...`) – Ňɏssa Pøngjǣrdenlarp Dec 24 '17 at 21:54
  • Thx you guys, I was looking at that docs and Rene's link before, but can't get it to work – Sergey Sypalo Dec 24 '17 at 23:25

1 Answers1

3

Unless you have a very specific use-case, I recommend using Newtonsoft.Json as your de-facto JSON library. It will save you a lot of trouble.

The problem is that instead of array this site returning just single object

Map objects to Dictionary.

Prefer automatic serialization/deserialization when possible:

using System.Collections.Generic;
using System.Net;

using Newtonsoft.Json;

namespace WhatToMine
{
    using MineBlob = Dictionary<string, Dictionary<string, CoinBlob>>;

    class CoinBlob
    {
        [JsonProperty(PropertyName = "id")]
        public int Id;
        [JsonProperty(PropertyName = "tag")]
        public string Tag;
        [JsonProperty(PropertyName = "algorithm")]
        public string Algorithm;
        [JsonProperty(PropertyName = "block_time")]
        public double BlockTime;
        [JsonProperty(PropertyName = "block_reward")]
        public double BlockReward;
        [JsonProperty(PropertyName = "block_reward24")]
        public double BlockReward24;
        [JsonProperty(PropertyName = "last_block")]
        public long LastBlock;
        [JsonProperty(PropertyName = "difficulty")]
        public double Difficulty;
        [JsonProperty(PropertyName = "difficulty24")]
        public double Difficulty24;
        [JsonProperty(PropertyName = "nethash")]
        public long NetHash;
        [JsonProperty(PropertyName = "exchange_rate")]
        public double ExchangeRate;
        [JsonProperty(PropertyName = "exchange_rate24")]
        public double ExchangeRate24;
        [JsonProperty(PropertyName = "exchange_rate_vol")]
        public double ExchangeRateVolume;
        [JsonProperty(PropertyName = "exchange_rate_curr")]
        public string ExchangeRateCurrency;
        [JsonProperty(PropertyName = "market_cap")]
        public string MarketCapUsd;
        [JsonProperty(PropertyName = "estimated_rewards")]
        public string EstimatedRewards;
        [JsonProperty(PropertyName = "estimated_rewards24")]
        public string EstimatedRewards24;
        [JsonProperty(PropertyName = "btc_revenue")]
        public string BtcRevenue;
        [JsonProperty(PropertyName = "btc_revenue24")]
        public string BtcRevenue24;
        [JsonProperty(PropertyName = "profitability")]
        public double Profitability;
        [JsonProperty(PropertyName = "profitability24")]
        public double Profitability24;
        [JsonProperty(PropertyName = "lagging")]
        public bool IsLagging;
        [JsonProperty(PropertyName = "timestamp")]
        public long TimeStamp;
    }

    class Program
    {
        const string JsonUrl = "http://whattomine.com/coins.json";

        static void Main(string[] args)
        {
            using (var client = new WebClient()) {
                var json = client.DownloadString(JsonUrl);
                var blob = JsonConvert.DeserializeObject<MineBlob>(json);
                // Do something with the data blob...
            }
        }
    }
}
Koby Duck
  • 1,118
  • 7
  • 15
  • Thx, Koby! That's what I'm looking for and yes, I'm using NetonSoft JSON. So to have all coins in dictionary value collection, just digged into the dictionary values: var blob = JsonConvert.DeserializeObject(json).Values.ElementAt(0).Values; – Sergey Sypalo Dec 24 '17 at 23:23