Json: 解析一个动态类型
Json: Parse a dynamic type
我正在尝试反序列化一些 Json:
{
"name": "foo",
"value": [ [ 1.2, 2.3, 4.5 ], [ 1.2, 2.3, 4.5 ] ]
}
进入此 C# class:
class Bar {
public string name { get; set; }
public object value { get; set; }
}
值是 object
类型,因为它可以是单个值或任何数组,...,值。
我试过使用原生 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
是 object[]
的 object[]
,实际上是 decimal
。问题是:我需要它们是 doubles
.
所以我尝试使用 Json.NET 库:
var data2 = JsonConvert.DeserializeObject<Bar>(
jsonString,
new JsonSerializerSettings { FloatParseHandling = FloatParseHandling.Double }
).value;
现在最终值是 double
类型,但我丢失了对象数组的结构,取而代之的是 JArray
of JArray
of double
。
所以我的问题是:是否可以配置本机 JavaScriptSerializer
class 以获得 doubles
而不是 decimals
或 是否可以制作 Json.NET return 个 objects
数组?
如果您的 Json for Value
属性 始终是一个数组(即使单个值是一个数组) - 那么您始终可以反序列化为 object[]
for 属性。这也将处理数组的数组。
{"name": "foo","value": [1.2]};
class Bar
{
public string name { get; set; }
public object[] value { get; set; }
}
如果不是这种情况,它可以是一个值本身,也可以是数组或数组的数组,那么您可能需要求助于实施自定义 JsonConverter 来满足您的业务需求。
https://www.newtonsoft.com/json/help/html/CustomJsonConverter.htm
由于value
的类型不固定我们可以说它是动态的,我们可以在C#中使用dynamic
关键字来表示属性:
class Bar
{
public string name { get; set; }
public dynamic value { get; set; }
}
这里我们在运行时发现value
的类型并相应地处理它。你可以自由地坚持使用 JavaScriptSerializer,就像我在这里所做的那样,或者如果你愿意,你可以看看用 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;
}
测试:
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));
}
控制台输出:
我正在尝试反序列化一些 Json:
{
"name": "foo",
"value": [ [ 1.2, 2.3, 4.5 ], [ 1.2, 2.3, 4.5 ] ]
}
进入此 C# class:
class Bar {
public string name { get; set; }
public object value { get; set; }
}
值是 object
类型,因为它可以是单个值或任何数组,...,值。
我试过使用原生 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
是 object[]
的 object[]
,实际上是 decimal
。问题是:我需要它们是 doubles
.
所以我尝试使用 Json.NET 库:
var data2 = JsonConvert.DeserializeObject<Bar>(
jsonString,
new JsonSerializerSettings { FloatParseHandling = FloatParseHandling.Double }
).value;
现在最终值是 double
类型,但我丢失了对象数组的结构,取而代之的是 JArray
of JArray
of double
。
所以我的问题是:是否可以配置本机 JavaScriptSerializer
class 以获得 doubles
而不是 decimals
或 是否可以制作 Json.NET return 个 objects
数组?
如果您的 Json for Value
属性 始终是一个数组(即使单个值是一个数组) - 那么您始终可以反序列化为 object[]
for 属性。这也将处理数组的数组。
{"name": "foo","value": [1.2]};
class Bar
{
public string name { get; set; }
public object[] value { get; set; }
}
如果不是这种情况,它可以是一个值本身,也可以是数组或数组的数组,那么您可能需要求助于实施自定义 JsonConverter 来满足您的业务需求。
https://www.newtonsoft.com/json/help/html/CustomJsonConverter.htm
由于value
的类型不固定我们可以说它是动态的,我们可以在C#中使用dynamic
关键字来表示属性:
class Bar
{
public string name { get; set; }
public dynamic value { get; set; }
}
这里我们在运行时发现value
的类型并相应地处理它。你可以自由地坚持使用 JavaScriptSerializer,就像我在这里所做的那样,或者如果你愿意,你可以看看用 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;
}
测试:
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));
}
控制台输出: