简体   繁体   English

杰森:解析动态类型

[英]Json: Parse a dynamic type

I'm trying to deserialize some Json: 我正在尝试反序列化一些Json:

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

into this C# class: 进入此C#类:

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. value是object类型的,因为它可以是单个值,也可以是值的数组的任何数组。

I've tried with the native C# class: 我已经尝试过使用本机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;

data1 is an object[] of object[] that are in fact decimal . data1object[]object[] ,实际上是decimal Problem is: I need them to be doubles . 问题是:我需要他们成为doubles

So I've tried with the Json.NET library: 因此,我尝试使用Json.NET库:

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 . 现在的最终值类型的double ,但我失去了对象数组的结构,并有代替JArrayJArraydouble

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 ? 所以我的问题是:是否可以将本机JavaScriptSerializer类配置为获取doubles而不是decimals 还是可以使Json.NET返回objects数组?

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: 由于value的类型不是固定的,我们可以说它是动态的,我们可以在C#中为该属性使用dynamic关键字:

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. 在这里,我们在运行时发现value的类型并进行相应处理。 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: 您可以自由使用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;
}

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: 控制台输出:

在此处输入图片说明

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. 如果您的Json for Value属性始终是一个数组(即使单个值是一个数组)-那么您可以始终将该属性反序列化为object[] 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. 如果不是这种情况,并且它可以是单独的值,也可以是数组或数组的数组,那么您可能需要诉诸实现自定义JsonConverter来满足您的业务需求。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM