C# receiving json string but unable to deserialize it

853 views Asked by At

i have an application that has to deserialize an array of data wrapped in a "results" Root Object, using Netwonsoft.Json package from NuGet

The Json string is exactly this:

{"results":[{"Coin":"SBD","LP":0.000269,"PBV":-54.36,"MACD1M":true,"MACD30M":true,"MACD1H":true,"MACD1D":true},{"Coin":"XMR","LP":0.027135,"PBV":11.44,"MACD1M":true,"MACD30M":true,"MACD1H":true,"MACD1D":true}]}

This Json string is created from a Console App i made, i wanted it to look like this https://bittrex.com/Api/v2.0/pub/market/GetTicks?marketName=BTC-NEO&tickInterval=hour

My class looks like this

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WindowsFormsApp2
{
    public class Result
    {
        public string Coins { get; set; }
        public decimal LastPrice { get; set; }
        public decimal PercentBuyVolume { get; set; }
    }

    public class RootObject
    {
        public List<Result> results { get; set; }
    }
}

In the Main form i have a function to download from a URL that Json (i have XAMPP running Apache) and deserialize it in an array. And it looks like this:

private void DownloadBittrexData()
        {

            int PanelID = 0;
            var Coin = new List<string>();
            var LastPrice = new List<decimal>();
            var PercentBuyVolume = new List<decimal>();
            var MACD1M = new List<bool>();
            var MACD30M = new List<bool>();
            var MACD1H = new List<bool>();
            var MACD1D = new List<bool>();

            var client = new WebClient();

            var URL = client.DownloadString("http://localhost/test.json");
            Console.WriteLine("Json String from URL: " + URL);
            var dataDeserialized = JsonConvert.DeserializeObject<RootObject>(URL);
            foreach (var data in dataDeserialized.results)
            {
                Coin.Add(data.Coins);
                LastPrice.Add(data.LastPrice);
                PercentBuyVolume.Add(data.PercentBuyVolume);

            }
            int sizeOfArrayClose = Coin.Count - 1;

            for (int i = 0; i <= sizeOfArrayClose; i++)
            {
                Console.WriteLine("Coin: " + Coin[i]);
                Console.WriteLine("Lastprice: " + LastPrice[i]);
                Console.WriteLine("PBV: " + PercentBuyVolume[i]);
            }
        }

Newtonsoft.Json is of course declared at the beginning of the form together with System.Net

using System.Net;
using Newtonsoft.Json;

The output looks like this:

Json String from URL: {"results":[{"Coin":"SBD","LP":0.000269,"PBV":-54.36,"MACD1M":true,"MACD30M":true,"MACD1H":true,"MACD1D":true},{"Coin":"XMR","LP":0.027135,"PBV":11.44,"MACD1M":true,"MACD30M":true,"MACD1H":true,"MACD1D":true}]}
Coin: 
Lastprice: 0
PBV: 0
Coin: 
Lastprice: 0
PBV: 0

It's like it fails to deserialize it after downloading it. What should i do? Thank you very much.

3

There are 3 answers

0
AnkUser On BEST ANSWER

I tried your exact code on my system and I was able to retrieve the result as expected. Hope this helps, It's easy to understand.

Here is the main class

 static void Main(string[] args)
    {

        RootObject configfile = LoadJson();

        foreach (var tResult in configfile.results)
        {
            Console.WriteLine("Coin: " + tResult.Coin);
            Console.WriteLine("Lastprice: " + tResult.LP);
            Console.WriteLine("PBV: " + tResult.PBV);
        }


        Console.ReadLine();

    }

LoadJson Function would be

 private static RootObject LoadJson()
    {
        string json = "{\"results\":[{\"Coin\":\"SBD\",\"LP\":0.000269,\"PBV\":-54.36,\"MACD1M\":true,\"MACD30M\":true,\"MACD1H\":true,\"MACD1D\":true},{\"Coin\":\"XMR\",\"LP\":0.027135,\"PBV\":11.44,\"MACD1M\":true,\"MACD30M\":true,\"MACD1H\":true,\"MACD1D\":true}]}";



        RootObject configs = Deserialize<RootObject>(json);
        return configs;
    }

and Deserialize function would be

private static T Deserialize<T>(string json)
    {
        T unsecureResult;
       string _DateTypeFormat = "yyyy-MM-dd HH:mm:ss";
        DataContractJsonSerializerSettings serializerSettings = new DataContractJsonSerializerSettings();
        DataContractJsonSerializer serializer;
        MemoryStream ms;
        unsecureResult = default(T);
        serializerSettings.DateTimeFormat = new System.Runtime.Serialization.DateTimeFormat(_DateTypeFormat);

        serializer = new DataContractJsonSerializer(typeof(T));
        ms = new MemoryStream(Encoding.Unicode.GetBytes(json));

        unsecureResult = (T)serializer.ReadObject(ms);

        return unsecureResult;
    }

and Now your Datamodel would be

public class Result
{

    public string Coin { get; set; }
    public double LP { get; set; }
    public double PBV { get; set; }
    public bool MACD1M { get; set; }
    public bool MACD30M { get; set; }
    public bool MACD1H { get; set; }
    public bool MACD1D { get; set; }

}

public class RootObject
{
    public List<Result> results { get; set; }
}
0
ANJYR On

your model should be like this for deserialize json

public class Result
{
    public string Coin { get; set; }
    public double LP { get; set; }
    public double PBV { get; set; }
    public bool MACD1M { get; set; }
    public bool MACD30M { get; set; }
    public bool MACD1H { get; set; }
    public bool MACD1D { get; set; }
}

public class RootObject
{
    public List<Result> results { get; set; }
}

LastPrice and PercentBuyVolume are not available in your model that's the reason it's getting an error.

2
spender On

Your property names don't map to the field names in the JSON. You could rename your C# properties to match the JSON, but it would make for unreadable downstream code.

Instead, you should map your properties (with nice, readable names) to the names that appear in the JSON, using JsonPropertyAttribute:

public class Result
{
    public string Coin { get; set; } //didn't bother here: changed property name to Coin
    [JsonProperty("LP")]
    public decimal LastPrice { get; set; }
    [JsonProperty("PBV")]
    public decimal PercentBuyVolume { get; set; }
}