Reputation: 13408
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
?
Upvotes: 1
Views: 2011
Reputation: 21548
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:
Upvotes: 2
Reputation: 4802
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
Upvotes: 0