Как сделать эту строку объектом JSON? - PullRequest
0 голосов
/ 28 марта 2020

Как я могу превратить строку, извлеченную из URL, в полезный объект? Я видел несколько Newtonsoft.Json примеров, но ни один из них не работает с макетом объекта в URL.

Код ниже - это то, что я имею до сих пор. (часть DeserializeObject в настоящее время в коде не работает) из-за расположения объекта.

JSON Данные:

{
    "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"
    }
}

код:

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;}
    }
}

Ответы [ 3 ]

2 голосов
/ 28 марта 2020

Ваш c# класс должен иметь структуру , похожую на json

( Примечание : я специально пропускаю некоторые детали десериализации для простоты, но вкратце части вашего C# класса, которые не соответствуют вашему json, будут пропущены - у вас будет default значений)

Вот что вы можете сделать

  1. Загрузите json из https://redutv-api.vg.no/corona/v1/sheets/norway-table-overview?region=county
  2. Создайте c# класс на основе этого json, используя какой-либо инструмент, например http://json2csharp.com/ или https://www.jsonutils.com/
  3. Переименуйте сгенерированный RootObject во что-то значимое - это ваш Statistics класс

В зависимости от инструмента вы получите немного другой результат, что-то похожее на код ниже

( Примечание : некоторые детали могут отличаться, например, типы сбора могут использовать массив, List<T> или IList<T> в зависимости от инструментария)

В качестве бонуса, если вы можете использовать. NET Core 3x, Попробуйте новый System.Text. Json APIs - это я Рекомендуемый подход в будущем, а не 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; }
}
0 голосов
/ 29 марта 2020
  /* 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);
0 голосов
/ 28 марта 2020

Вам нужна структура объекта в C#, которая соответствует структуре JSON, которую вы загружаете.

Такие сайты, как json2csharp автоматически создадут структуру для вас и будет работать с большинством JSON, о котором вы только можете подумать.

Для данных, представленных этим URL, когда я только что посетил его, предлагается следующее:

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; }
}

Затем вы можете запустить

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

для десериализации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...