svemal
svemal

Reputation: 87

How do i make this string a JSON object?

How can I turn the string fetched from the URL to a usable object? I've seen several Newtonsoft.Json examples, but none of them work with the layout of the object in the URL.

The code below is what I have so far. (the DeserializeObject part currently in the code doesn't work) due to the layout of the object.

JSON Data:

{
    "totals": {
        "confirmed": 4011,
        "dead": 23,
        "recovered": 7,
        "changes": {
            "newToday": 239,
            "newYesterday": 378,
            "diff": -139,
            "deathsToday": 4,
            "deathsYesterday": 5
        }
    },
    "cases": [
        {
            "confirmed": 989,
            "dead": 4,
            "recovered": 1,
            "name": "Oslo",
            "countyCode": "03",
            "confirmedPer1kCapita": 1.426111833700075
        },
        {
            "confirmed": 1138,
            "dead": 7,
            "recovered": 1,
            "name": "Viken",
            "countyCode": "30",
            "confirmedPer1kCapita": 0.9168805114549636
        },
        {
            "confirmed": 284,
            "dead": 2,
            "recovered": 1,
            "name": "Innlandet",
            "countyCode": "34",
            "confirmedPer1kCapita": 0.7647050904048359
        },
        {
            "confirmed": 440,
            "dead": 0,
            "recovered": 3,
            "name": "Vestland",
            "countyCode": "46",
            "confirmedPer1kCapita": 0.6912467735271338
        },
        {
            "confirmed": 304,
            "dead": 0,
            "recovered": 0,
            "name": "Rogaland",
            "countyCode": "11",
            "confirmedPer1kCapita": 0.633475865403049
        },
        {
            "confirmed": 285,
            "dead": 0,
            "recovered": 0,
            "name": "Trøndelag",
            "countyCode": "50",
            "confirmedPer1kCapita": 0.608062265575995
        },
        {
            "confirmed": 130,
            "dead": 2,
            "recovered": 0,
            "name": "Troms og Finnmark",
            "countyCode": "54",
            "confirmedPer1kCapita": 0.5342956134330138
        },
        {
            "confirmed": 159,
            "dead": 1,
            "recovered": 0,
            "name": "Agder",
            "countyCode": "42",
            "confirmedPer1kCapita": 0.5175259007066344
        },
        {
            "confirmed": 149,
            "dead": 1,
            "recovered": 0,
            "name": "Vestfold og Telemark",
            "countyCode": "38",
            "confirmedPer1kCapita": 0.3552728209138857
        },
        {
            "confirmed": 91,
            "dead": 0,
            "recovered": 1,
            "name": "Møre og Romsdal",
            "countyCode": "15",
            "confirmedPer1kCapita": 0.34308809446610217
        },
        {
            "confirmed": 42,
            "dead": 0,
            "recovered": 0,
            "name": "Nordland",
            "countyCode": "18",
            "confirmedPer1kCapita": 0.17410408937343255
        }
    ],
    "updated": {
        "ts": "2020-03-28T21:23:18+01:00",
        "by": "Morten Asbjørnsen",
        "version": "5154"
    }
}

Code:

public class Program
{
    public static void Main(string[] args)
    {
        string Address = "https://redutv-api.vg.no/corona/v1/sheets/norway-table-overview?region=county";

        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Address);
        HttpWebResponse response = (HttpWebResponse)request.GetResponse();


        if (response.StatusCode == HttpStatusCode.OK)
        {
            Stream receiveStream = response.GetResponseStream();
            StreamReader readStream = null;

            if (String.IsNullOrWhiteSpace(response.CharacterSet))
                readStream = new StreamReader(receiveStream);
            else
                readStream = new StreamReader(receiveStream, Encoding.GetEncoding(response.CharacterSet));

            string data = readStream.ReadToEnd();

            response.Close();
            readStream.Close();
            Console.WriteLine(data);

            //No clue...
            Statistic statistic = JsonConvert.DeserializeObject<Statistic>(data);   

        }
    }

    public class Statistic
    {   
        //needs modifying.
        public string confirmed.total {get;set;}
    }
}

Upvotes: 0

Views: 129

Answers (3)

OO7
OO7

Reputation: 690

  /* method arguments:
      stream : Stream class instance
      charSet: Character set (in string), default is current system encoding.
      bufferSize: Buffer size, default 1024 bytes
   */
  static async Task<string> readStreamAsync(Stream stream, string charSet = "", int bufferSize = 1024)
  {
        /* read stream to buffers */

        var buffer = new byte[bufferSize];
        List<byte> buffers = new List<byte>();

        using (var readStream = new StreamReader(stream))
        {
            // read stream into buffer
            var n = await readStream.ReadAsync(buffer, 0, bufferSize);

            // loop buffer streaming until no more stream data
            while (n > 0)
            {
                // populate buffer into buffer list
                buffers.AddRange(new ArraySegment<byte>(buffer, 0, n).Array);

                // read stream into buffer
                n = await readStream.ReadAsync(buffer, 0, bufferSize);
            }
        }

        /* return encoded string */

        if (String.IsNullOrWhiteSpace(charSet))
        {
            // encode buffers array into default encoded string
            return Encoding.Default.GetString(buffers.ToArray());
        }
        else
        {
            // encode buffers array into encoded string based on any character set
            return Encoding.GetEncoding(charSet).GetString(buffers.ToArray());
        }
  }

  /* usage: */

  string data;

  try
  {
      using (var receiveStream = response.GetResponseStream())
      {
          data = await readStreamAsync(receiveStream, response.CharacterSet);
      }
  }
  finally
  {
      response.Close();
  }

  Console.WriteLine(data);

  Statistic statistic = JsonConvert.DeserializeObject<Statistic>(data);

Upvotes: 0

ironstone13
ironstone13

Reputation: 3443

Your c# class has to have structure similar to json

(Note: I'm specifically skipping some details of deserialization for simplicity, but in short the parts of your C# class that don't match your json will be skipped - you will have default values)

Here's what you can do

  1. Download your json from https://redutv-api.vg.no/corona/v1/sheets/norway-table-overview?region=county
  2. Generate a c# class based on that json using some tool, for example http://json2csharp.com/ or https://www.jsonutils.com/
  3. Rename the generated RootObject into something meaningful - this is your Statistics class

Depending on the tooling you will get a slightly different result, something similar to the code below

(Note: Some details may differ, like collection types can use array, List<T> or IList<T> depending on the tooling)

As a bonus, if you're able to use .NET Core 3x, Try the new System.Text.Json APIs - this is the recommended approach going forward, not Newtonsoft.JSON

public class Changes
{
    public int newToday { get; set; }
    public int newYesterday { get; set; }
    public int diff { get; set; }
    public int deathsToday { get; set; }
    public int deathsYesterday { get; set; }
}

public class Totals
{
    public int confirmed { get; set; }
    public int dead { get; set; }
    public int recovered { get; set; }
    public Changes changes { get; set; }
}

public class Case
{
    public int confirmed { get; set; }
    public int dead { get; set; }
    public int recovered { get; set; }
    public string name { get; set; }
    public string countyCode { get; set; }
    public double confirmedPer1kCapita { get; set; }
}

public class Updated
{
    public DateTime ts { get; set; }
    public string by { get; set; }
    public string version { get; set; }
}

public class RootObject
{
    public Totals totals { get; set; }
    public List<Case> cases { get; set; }
    public Updated updated { get; set; }
}

Upvotes: 2

ADyson
ADyson

Reputation: 61849

You need an object structure in C# which matches the structure of the JSON you're downloading.

Sites like json2csharp will auto-generate a structure for you and will work with most JSON you can think of.

For the data presented by that URL when I visited it just now, it suggests this:

public class Changes
{
    public int newToday { get; set; }
    public int newYesterday { get; set; }
    public int diff { get; set; }
    public int deathsToday { get; set; }
    public int deathsYesterday { get; set; }
}

public class Totals
{
    public int confirmed { get; set; }
    public int dead { get; set; }
    public int recovered { get; set; }
    public Changes changes { get; set; }
}

public class Case
{
    public int confirmed { get; set; }
    public int dead { get; set; }
    public int recovered { get; set; }
    public string name { get; set; }
    public string countyCode { get; set; }
    public double confirmedPer1kCapita { get; set; }
}

public class Updated
{
    public DateTime ts { get; set; }
    public string by { get; set; }
    public string version { get; set; }
}

public class RootObject
{
    public Totals totals { get; set; }
    public List<Case> cases { get; set; }
    public Updated updated { get; set; }
}

You can then run

RootObject obj = JsonConvert.DeserializeObject<RootObject>(data); 

to deserialise it.

Upvotes: 0

Related Questions