Конвертировать JSON в список объектов - PullRequest
2 голосов
/ 07 апреля 2019

Я определил класс Quote следующим образом:

public class Quote
{
    public double Price { get; set; }
    public string Symbol { get; set; }
}

Следующая конечная точка JSON возвращается конечной точкой отдыха Web API и не содержит явного поля symbol.Символы являются именованными объектами, например, AAPL, GOOG, FB:

{                       
    "AAPL": {           
        "price": 205    
    },                  
    "GOOG": {           
        "price": 1230.38
    },                  
    "FB": {             
        "price": 178.41 
    }                   
}    

Как лучше всего преобразовать этот JSON в List<Quote>?

Ответы [ 2 ]

3 голосов
/ 07 апреля 2019

Один простой подход, чтобы справиться с вашей хитрой частью JSON

1) Десериализовать ваш JSON до Dictionary<string, dynamic>.

2) Затем сгладьте ваш словарный результат до List<Quote>.

string json = File.ReadAllText(@"Path to your json");

List<Quote> quotes = JsonConvert.DeserializeObject<Dictionary<string, dynamic>>(json)
    .Select(x => new Quote
    {
        Symbol = x.Key,
        Price = x.Value.price    //<= x.Value is dynamic type so you can access your key with dot(.) separator
    })
    .ToList();


//-------------Print the result to Console-------------

Console.WriteLine("Symbol\tPrice");
Console.WriteLine("----------------------");
foreach (var quote in quotes)
{
    Console.WriteLine(quote.Symbol +"\t" + quote.Price);
}

Альтернатива:

Вы можете использовать JToken вместо dynamic,

List<Quote> quotes = JsonConvert.DeserializeObject<Dictionary<string, JToken>>(json)
    .Select(x => new Quote
    {
        Symbol = x.Key,
        Price = Convert.ToDouble(x.Value["price"])
    })
    .ToList();

Выход:

enter image description here

2 голосов
/ 07 апреля 2019

Вы можете сделать пользовательский JsonConverter для преобразования этой структуры JSON в нужный вам формат List<Quote>.

using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

public class QuoteListConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(List<Quote>);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        JObject obj = JObject.Load(reader);
        return obj.Properties()
                  .Select(p => new Quote
                  {
                      Symbol = p.Name,
                      Price = p.Value["price"].ToObject<double>()
                  })
                  .ToList();
    }

    public override bool CanWrite
    {
        get { return false; }
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

Затем использовать его так:

var quotes = JsonConvert.DeserializeObject(json, new QuoteListConverter());

Рабочая демоверсия: https://dotnetfiddle.net/kcU8DO

...