1

I'm trying to deserialize some Json:

{
    "name": "foo",
    "value": [ [ 1.2, 2.3, 4.5 ], [ 1.2, 2.3, 4.5 ] ]
}

into this C# class:

class Bar {
    public string name { get; set; }
    public object value { get; set; }
}

value is of type object because it can be a single value or any array of array, of..., of values.

I've tried with the native C# class:

string jsonString = @"{
    ""name"": ""foo"",
    ""value"": [ [ 1.2, 2.3, 4.5 ], [ 1.2, 2.3, 4.5 ] ]
}";
var data1 = new JavaScriptSerializer().Deserialize<Bar>(jsonString).value;

data1 is an object[] of object[] that are in fact decimal. Problem is: I need them to be doubles.

So I've tried with the Json.NET library:

var data2 = JsonConvert.DeserializeObject<Bar>(
    jsonString,
    new JsonSerializerSettings { FloatParseHandling = FloatParseHandling.Double }
).value;

Now the final values are of type double but I lost the structure of arrays of objects, and have instead a JArray of JArray of double.

So my question is: Is it possible to configure the native JavaScriptSerializer class to get doubles instead of decimals or is it possible to make Json.NET return arrays of objects?

gregseth
  • 12,952
  • 15
  • 63
  • 96
  • 3
    Have you tried declaring `value` as type of `double[][]` ? – Matt Feb 08 '18 at 15:57
  • You could use Newtonsoft to deserialize into a dynamic, then test the value if it is an array or a double, then do whatever. – Greg Feb 08 '18 at 16:00
  • @Matt I think his issue is values could be 8 or it could be [8, 9, 10] so it is either double[] or double[][]. – Greg Feb 08 '18 at 16:52
  • Yes it can be absolutely anything single value (not necessarily a double) or even mixed type arrays, hence the use of generic type object[]. – gregseth Feb 08 '18 at 16:58
  • 1
    Using Json.NET your `value` object will come back as a `JArray`. If you don't want that, you can convert it to a primitive list or array using a recursive method like the one shown in [How do I use JSON.NET to deserialize into nested/recursive Dictionary and List?](https://stackoverflow.com/a/19140420). – dbc Feb 08 '18 at 19:33

2 Answers2

2

As the type of value is not fixed we can say it is dynamic, and we can use the dynamic keyword in C# for that property:

class Bar
{
    public string name { get; set; }
    public dynamic value { get; set; }
}

Here we discover the type of value at runtime and process it accordingly. You are free to stick with the JavaScriptSerializer as I have done here or if you prefer you could look at implementing something similar with Newtonsoft:

List<double> ParseFoo(string jsonString)
{
    var data1 = new JavaScriptSerializer().Deserialize<Bar>(jsonString).value;
    var r = new List<double>();

    // We can handle a single value, an array, or an array of arrays:
    var array = data1 as object[];
    if (array != null)
    {
        foreach (object obj in array)
        {
            decimal? number = obj as decimal?;
            if (number.HasValue)
                r.Add((double)number.Value);
            else
                r.AddRange((obj as object[]).Cast<decimal>().Select(d => (double)d));
        }
    } else
    {
        r.Add((double)data1);
    }

    return r;
}

Testing:

void Main()
{
    string jsonString = @"{
    ""name"": ""foo"",
    ""value"": [ [ 1.2, 2.3, 4.5 ], [ 1.2, 2.3, 4.5 ] ]
    }";

    Console.WriteLine(ParseFoo(jsonString));

    jsonString = @"{
    ""name"": ""foo"",
    ""value"": [ 1.2, 2.3, 4.5 ]
    }";

    Console.WriteLine(ParseFoo(jsonString));

    jsonString = @"{
    ""name"": ""foo"",
    ""value"": 2.7
    }";

    Console.WriteLine(ParseFoo(jsonString));
}

Console output:

enter image description here

Stephen Kennedy
  • 20,585
  • 22
  • 95
  • 108
0

If your Json for Value property is always an array (even if the single value is an array) - then you can always deserialize into object[] for that property. That will handle arrays of arrays as well.

    {"name": "foo","value": [1.2]};

    class Bar
    {
        public string name { get; set; }
        public object[] value { get; set; }
    }

If that is not the case and it can be either a value on its own or array or array of arrays then you might need to resort to implementing custom JsonConverter to account for your business requirements.

https://www.newtonsoft.com/json/help/html/CustomJsonConverter.htm

Vidmantas Blazevicius
  • 4,652
  • 2
  • 11
  • 30