-1

The Json response is like this:

[
    [
        1597276800000,
        "16.46340000",
        "18.34880000",
        "15.91750000",
        "17.18830000",
        "30941693.96000000",
        1597363199999,
        "527277033.75007300",
        681520,
        "15434492.74000000",
        "263241680.21583200",
        "0"
    ],
    [
        1597363200000,
        "17.17280000",
        "17.59980000",
        "16.30000000",
        "16.86580000",
        "11130678.41000000",
        1597449599999,
        "188347963.49490200",
        244865,
        "5421845.98000000",
        "91775690.92871400",
        "0"
    ]
]

I know the labels of these properties but they are not in the json document. This is how the response looks in the json viewer in vs. enter image description here when I convert with json2csharp.com I get these:

    public class Root    {
        public List<List<object>> MyArray { get; set; } 
    }

and 

Root myDeserializedClass = JsonConvert.DeserializeObject(myJsonResponse); 

the compiler complains:

because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly.
To fix this error either change the JSON to a JSON object (e.g. {"name":"value"}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List<T> that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array.

A list of list or an array of list should work but I keep getting the same error message.

Any ideas?

Thanks

Alawna
  • 33
  • 1
  • 6

3 Answers3

4

You dont have a json with objects, simply a list that contains another list of strings.

You should deserialize like this,

var obj = JsonConvert.DeserializeObject<List<List<string>>>(myJsonResponse);
Jawad
  • 11,028
  • 3
  • 24
  • 37
  • You could also deserialize it into an array of string arrays if you wanted to. – Flydog57 Aug 15 '20 at 00:32
  • Honestly my personal preference is always List. You can deserialize to arrays as well but I find its easier to work with List :) – Jawad Aug 15 '20 at 00:38
  • Oh, I agree. I was just pointing out the option. – Flydog57 Aug 15 '20 at 00:41
  • In this case, we don't consider the types that are returned from the JSON response. This would probably lead to more casting later on. – Julien Aug 15 '20 at 12:31
2

The easiest way would be to build a JsonConverter to be able to manipulate objects. It the data you Json response always has the same structure, I assume it would be easier to manipulate.

Here is some quick code that I put together for a custom JsonConverter:

public class DataObjectConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(DataObject);
    }
    public override bool CanRead => true;
    public override bool CanWrite => false;

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.Null)
            return null;
        var array = JArray.Load(reader);
        var dataObj = (existingValue as DataObject ?? new DataObject());
        dataObj.PropertyA = (long)array.ElementAtOrDefault(0);
        dataObj.PropertyB = (string)array.ElementAtOrDefault(1);
        dataObj.PropertyC = (string)array.ElementAtOrDefault(2);
        dataObj.PropertyD = (string)array.ElementAtOrDefault(3);
        dataObj.PropertyE = (string)array.ElementAtOrDefault(4);
        dataObj.PropertyF = (string)array.ElementAtOrDefault(5);
        dataObj.PropertyG = array.ElementAtOrDefault(6).ToObject<long>();
        dataObj.PropertyH = (string)array.ElementAtOrDefault(7);
        dataObj.PropertyI = (int)array.ElementAtOrDefault(8);
        dataObj.PropertyJ = (string)array.ElementAtOrDefault(9);
        dataObj.PropertyK = (string)array.ElementAtOrDefault(10);
        dataObj.PropertyL = (string)array.ElementAtOrDefault(11);
        return dataObj;
    }

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

I created a dummy object to be able to extract each field with their actual types.

class DataObject
{
    public long PropertyA { get; set; }
    public string PropertyB { get; set; }
    public string PropertyC { get; set; }
    public string PropertyD { get; set; }
    public string PropertyE { get; set; }
    public string PropertyF { get; set; }
    public long PropertyG { get; set; }
    public string PropertyH { get; set; }
    public long PropertyI { get; set; }
    public string PropertyJ { get; set; }
    public string PropertyK { get; set; }
    public string PropertyL { get; set; }
}

You can then use this CustomJsonConverter as follows:

    //Extract Typed List
    var typedData = JsonConvert.DeserializeObject<List<DataObject>>(json, new DataObjectConverter());
Dharman
  • 30,962
  • 25
  • 85
  • 135
Julien
  • 437
  • 4
  • 11
-1

Option 1

Instead of object, you can use dynamic. It's properties and behaviors are resolved at runtime.

You can then perform casting - I've only done this before using low level unsafe context like this:

public class Root
{
  public dynamic[][] MyArray { get; set; }
}
// ...
fixed (byte* ptr = root.MyArray)
{
  // conversion logic
}

Option 2

It doesn't take too long to write your own JSON parser, especially if it is not intended to be generic.