反序列化复杂JSON

时间:2013-12-20 14:03:54

标签: c# json json.net deserialization

我正在尝试反序列化以下JSON字符串:

Link to JSON String

{
  "result": 1,
  "error": null,
  "id": 0,
  "data": {
    "ASTEALTHYNODE01_0301_0_30": {
        "css_class": "sensor rf digital humidity",
        "default_name": "Humidity",
        "device_type": "humidity",
        "did": "30",
        "gid": "0301",
        "has_subdevice_count": 0,
        "has_time_series": 1,
        "is_actuator": 0,
        "is_sensor": 1,
        "is_silent": 0,
        "last_data": {
            "DA": 58,
            "timestamp": 1355791804474
        },
        "meta": {},
        "node": "ASTEALTHYNODE01",
        "shortName": "Humidity",
        "subDevices": {},
        "vid": "0"
    },
    "ASTEALTHYNODE01_0301_0_31": {
        "css_class": "sensor rf digital temperature",
        "default_name": "Temperature",
        "device_type": "temperature",
        "did": "31",
        "gid": "0301",
        "has_subdevice_count": 0,
        "has_time_series": 1,
        "is_actuator": 0,
        "is_sensor": 1,
        "is_silent": 0,
        "last_data": {
            "DA": 26.6,
            "timestamp": 1355791804475
        },
        "meta": {},
        "node": "ASTEALTHYNODE01",
        "shortName": "Temperature",
        "subDevices": {},
        "vid": "0"
    },
    "ASTEALTHYNODE01_0_0_1000": {
        "css_class": "actuator cape led rgbled",
        "default_name": "On Board RGB LED",
        "device_type": "rgbled",
        "did": "1000",
        "gid": "0",
        "has_subdevice_count": 0,
        "has_time_series": 0,
        "is_actuator": 1,
        "is_sensor": 1,
        "is_silent": 0,
        "last_data": {
            "DA": "22B42B",
            "timestamp": 1355790209080
        },
        "meta": {},
        "node": "ASTEALTHYNODE01",
        "shortName": "On Board RGB LED",
        "subDevices": {},
        "vid": "0"
    },
    "ASTEALTHYNODE01_0_0_11": {
        "css_class": "sensor serial rf rf433 receiver transmitter",
        "default_name": "RF 433Mhz",
        "device_type": "rf433",
        "did": "11",
        "gid": "0",
        "has_subdevice_count": 1,
        "has_time_series": 0,
        "is_actuator": 1,
        "is_sensor": 1,
        "is_silent": 0,
        "last_data": {
            "DA": "010001010101010100010101",
            "timestamp": 1355789891324
        },
        "meta": {},
        "node": "ASTEALTHYNODE01",
        "shortName": "RF 433Mhz",
        "subDevices": {
            "6l8At": {
                "category": "rf",
                "data": "011111110001010100110000",
                "shortName": "Door Bell",
                "type": "sensor"
            }
        },
        "vid": "0"
    }
  }
}

我通常在http://json2csharp.com的帮助下创建类,然后我做这样的事情(Json.NET libary): 折叠|复制代码

var result = JsonConvert.DeserializeObject<MyObject>(jsonString);

但在获取JSON字符串之前,设备及其名称的数量(例如:ASTEALTHYNODE01_0_0_11)是未知的。我怎样才能反序化呢?

谢谢

2 个答案:

答案 0 :(得分:0)

您的json“data”属性看起来像属性为Dictionary&lt;的属性string,SomeClass&gt;,其中SomeClass - 是

的类
    {
        "css_class": "sensor rf digital humidity",
// skipped
       "subDevices": {},
        "vid": "0"
    },

数据结构,因此您可以在MyObject类中定义此属性并使用强类型反序列化而不会出现任何问题。

答案 1 :(得分:0)

这适用于我,使用您的JSON,并使用JSON.NET:

        Payload payloadJsonNet = JsonConvert.DeserializeObject<Payload>(data);
        System.Diagnostics.Debug.Assert
        (
            payloadJsonNet.data.ContainsKey("ASTEALTHYNODE01_0_0_11") &&
            payloadJsonNet.data["ASTEALTHYNODE01_0_0_11"].subDevices.ContainsKey("6l8At") &&
            payloadJsonNet.data["ASTEALTHYNODE01_0_0_11"].subDevices["6l8At"].shortName == "Door Bell"
        );

...如果您准备了以下POCO(例如,使用漂亮的json2csharp助手):

    public class Payload
    {
        public int result { get; set; }
        public int id { get; set; }
        public Error error { get; set; }
        public Dictionary<string, Device> data { get; set; }
    }

    public class Device
    {
        public string css_class { get; set; }
        public string default_name { get; set; }
        public string device_type { get; set; }
        public string did { get; set; }
        public string gid { get; set; }
        public int has_subdevice_count { get; set; }
        public int has_time_series { get; set; }
        public int is_actuator { get; set; }
        public int is_sensor { get; set; }
        public int is_silent { get; set; }
        public LastData last_data { get; set; }
        public Meta meta { get; set; }
        public string node { get; set; }
        public string shortName { get; set; }
        public Dictionary<string, Device> subDevices { get; set; }
        public string vid { get; set; }
    }

    public class LastData
    {
        public string DA { get; set; }
        public long timestamp { get; set; }
    }

    public class Meta
    {
    }

    public class Error
    {
    }

我想你必须从其他JSON输入中找出/推断这些最后两个人的属性(即“Meta”和“Error”)。

另请注意,需要使用的“long”类型:

    public class LastData
    {
        public string DA { get; set; }
        public long timestamp { get; set; }
    }

最后,只是为了好奇,my own parser反序列化它也很好:

        Payload payloadMyParser = new JsonParser().Parse<Payload>(data);
        System.Diagnostics.Debug.Assert
        (
            payloadMyParser.data.ContainsKey("ASTEALTHYNODE01_0_0_11") &&
            payloadMyParser.data["ASTEALTHYNODE01_0_0_11"].subDevices.ContainsKey("6l8At") &&
            payloadMyParser.data["ASTEALTHYNODE01_0_0_11"].subDevices["6l8At"].shortName == "Door Bell"
        );

'希望这有帮助,