Json:解析动态类型

时间:2018-02-08 15:52:30

标签: c# arrays json json.net javascriptserializer

我正在尝试反序列化一些Json:

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

进入这个C#类:

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

值的类型为object,因为它可以是单个值或任何值的数组数组。

我尝试过使用原生C#类:

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;

data1object[] object[],实际上是decimal。问题是:我需要它们为doubles

所以我尝试过使用Json.NET库:

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

现在最终值的类型为double,但我丢失了对象数组的结构,而是JArray JArray double

所以我的问题是:是否可以配置原生JavaScriptSerializer类来获取doubles而不是decimals 是否可以制作Json。 NET返回数组objects

2 个答案:

答案 0 :(得分:2)

由于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));
}

控制台输出:

enter image description here

答案 1 :(得分:0)

如果您的Value属性的Json始终是一个数组(即使单个值是一个数组) - 那么您始终可以为该属性反序列化为object[]。这也将处理数组的数组。

    {"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