Home > Mobile >  Deserialize none standard Json with System.Text.Json
Deserialize none standard Json with System.Text.Json

Time:08-04

I have to deserialize into a object the following json string:

var jsonString = @"[[{""OU2CJ3-UBRYG-KCPVS6"":{""cost"":""27187.08000"",""vol_exec"":""3.40000000"",""fee"":""27.18708"",""avg_price"":""7996.20000""}}]]";

Into a model, for instance like the following one :

public class OrderInfo
{
    public string OrderId { get; set; }
    public Info Info { get; set; }
}

public class Info
{
    public decimal avg_price { get; set; }

    public decimal cost { get; set; }

    public decimal fee { get; set; }

    public decimal vol_exec { get; set; }
}

I have tried without success with this kind of code:

var nodes = JsonNode.Parse(jsonString);
foreach (var order in nodes[0].AsArray())
{
  // ??
}

Or :

var info = JsonSerializer.Deserialize<OrderInfo>(jsonString);

How can I handle a Json without clear {"Property": "name"} structure by using System.Text.Json framework ?

CodePudding user response:

First of all, your Info class isn't correct. The values coming in the JSON are strings since they are wrapped with double quotes. So it should look like this:

public class Info
{
    public string avg_price { get; set; }
    public string cost { get; set; }
    public string fee { get; set; }
    public string vol_exec { get; set; }
}

Secondly, this JSON is actually an array of arrays.

Thirdly, you can use a Dictionary to cope with the changing property names.

So to deserialise, you can do something like this:

var result = JsonSerializer.Deserialize<Dictionary<string, Info>[][]>(jsonString);

foreach (var element in result)
{
    foreach (var innerElement in element)
    {
        foreach(var dictionaryItem in innerElement)
        {
            var key = dictionaryItem.Key;
            var info = dictionaryItem.Value;
            
            var avgPrice = info.avg_price;
        }

    }
}

CodePudding user response:

This code would be much more simple if you use Newtonsoft.Json, but since you are using Text.Json this code could be enough for your json

    var data = JsonSerializer.Deserialize<List<List<Dictionary<string,Info>>>>(jsonString);

    Info info = data[0][0].Values.First();

    decimal cost = info.Cost;

if you have several items, this code is more generic

List<OrderInfo> infos = jsonParsed.SelectMany(d => d.ToList())
    .SelectMany(v => ((JObject)v).Properties()
    .Select(d => new OrderInfo { OrderId = d.Name, Info = d.Value.ToObject<Info>()})
    .ToList())
    .ToList();

class Info

public partial class Info
{
    public string cost { set { Cost = Convert.ToDecimal(value); } }
    public decimal Cost { get; set; }

    public string vol_exec { set { VolExec = Convert.ToDecimal(value); } }
    public decimal VolExec { get; set; }

    public string fee { set { Fee = Convert.ToDecimal(value); } }
    public decimal Fee { get; set; }

    public string avg_price { set { AvgPrice = Convert.ToDecimal(value); } }
    public decimal AvgPrice { get; set; }
}
  • Related