繁体   English   中英

为嵌套API在C#中反序列化json

[英]Deserializing json in c# for the nest-api

我正在尝试使用c#,newtonsoft和.net 3.5来反序列化下面的Devices json结构,但由于“ qxdddh”和“ q0tL6au”是动态生成的名称,因此无法生成可以工作的代码。

最终为结构中的每个恒温器创建一个恒温器类的列表或数组(在本例中为“ qxdddh”和“ q0tL6au”)。

{
    "thermostats": {
        "qxdddh": {
            "locale": "en-US",
            "temperature_scale": "F",
            "is_using_emergency_heat": false,
            "has_fan": true,
            "software_version": "4.1",
            "has_leaf": true,
            "device_id": "qxdddh",
            "name": "",
            "can_heat": true,
            "can_cool": true,
            "hvac_mode": "heat",
            "target_temperature_c": 12.5,
            "target_temperature_f": 55,
            "target_temperature_high_c": 24.0,
            "target_temperature_high_f": 75,
            "target_temperature_low_c": 20.0,
            "target_temperature_low_f": 68,
            "ambient_temperature_c": 21.0,
            "ambient_temperature_f": 70,
            "away_temperature_high_c": 24.0,
            "away_temperature_high_f": 76,
            "away_temperature_low_c": 12.5,
            "away_temperature_low_f": 55,
            "structure_id": "ryWu-tRQstxux0tYhmZ8ESsrGgDjDQ",
            "fan_timer_active": false,
            "name_long": "Thermostat",
            "is_online": true
        },
        "q0tL6au": {
            "locale": "en-US",
            "temperature_scale": "F",
            "is_using_emergency_heat": false,
            "has_fan": true,
            "software_version": "4.1",
            "has_leaf": true,
            "device_id": "q0tL6au",
            "name": "Den",
            "can_heat": false,
            "can_cool": true,
            "hvac_mode": "off",
            "target_temperature_c": 20.5,
            "target_temperature_f": 69,
            "target_temperature_high_c": 24.0,
            "target_temperature_high_f": 75,
            "target_temperature_low_c": 20.0,
            "target_temperature_low_f": 68,
            "ambient_temperature_c": 23.0,
            "ambient_temperature_f": 73,
            "away_temperature_high_c": 24.0,
            "away_temperature_high_f": 76,
            "away_temperature_low_c": 12.5,
            "away_temperature_low_f": 55,
            "structure_id": "ryWu-tqNu0tYhmZ8ESsrGgDjDQ",
            "fan_timer_active": false,
            "name_long": "Den Thermostat",
            "is_online": true
        }
    }
}

最初的代码尝试是

    public class Devices
    {
        public TstatDetails[] thermostats { get; set; }
    }

    public class TstatDetails
    {
         public string locale { get; set; }
         public string temperature_scale { get; set; }
         public string is_using_emergency_heat { get; set; }
         public string has_fan { get; set; }
         public string software_version { get; set; }
         public string has_leaf { get; set; }
         public string device_id { get; set; }
         public string name { get; set; }
         public string can_heat { get; set; }
         public string can_cool { get; set; }
         public string hvac_mode { get; set; }
         public string target_temperature_c { get; set; }
         public string target_temperature_f { get; set; }
         public string target_temperature_high_c { get; set; }
         public string target_temperature_high_f { get; set; }
         public string target_temperature_low_c { get; set; }
         public string target_temperature_low_f { get; set; }
         public string ambient_temperature_c { get; set; }
         public string ambient_temperature_f { get; set; }
         public string away_temperature_high_c { get; set; }
         public string away_temperature_high_f { get; set; }
         public string away_temperature_low_c { get; set; }
         public string away_temperature_low_f { get; set; }
         public string structure_id { get; set; }
         public string fan_timer_active { get; set; }
         public string name_long { get; set; }
         public string is_online { get; set; }
    }

Devices tstats = (Devices) Newtonsoft.Json.JsonConvert.DeserializeObject<Devices>(jsonstring);

产生并带有以下说明的异常

无法反序列化当前JSON对象(例如{“ name”:“ value”})为类型'NestTest.NestOAuth2 + TstatDetails []',因为该类型需要JSON数组(例如[1,2,3])才能正确反序列化。

要解决此错误,可以将JSON更改为JSON数组(例如[1,2,3]),也可以更改反序列化类型,使其成为普通的.NET类型(例如,不像整数这样的原始类型,也不像这样的集合类型)数组或列表),可以从JSON对象反序列化。 还可以将JsonObjectAttribute添加到类型中,以强制其从JSON对象反序列化。

我理解错误(我认为),但是对于C#来说还很陌生,因此不确定如何针对这种情况进行纠正。

只需将Devices类更改为使用Dictionary<,>而不是数组即可:

public class Devices
{
    public Dictionary<string, TstatDetails> thermostats { get; set; }
}

JSON.NET将JSON中的thermostats对象的每个属性解释为字典中的一个条目,并适当地填充它。 (您的调用代码保持完全相同。)

然后,您将通过ID获得所有恒温器。 例如:

TstatDetails details = tstats["qxdddh"];

一旦可行,我强烈建议您尝试使所有属性名称更加传统:)

您的Json对象应该是一个数组,而不仅仅是一个对象。

它基本上应该用[ .... ] (在其中肯定可以有多个对象 )包装,而不要用{ ... }包装。

它可能看起来类似于:

[
        {
            "locale": "en-US",
            "temperature_scale": "F",
            "is_using_emergency_heat": false,
            ...
        },
        {
            "locale": "en-US",
            "temperature_scale": "F",
            "is_using_emergency_heat": false,
            ...
        }
]

编辑

好吧,我无法与The Skeet竞争。 但是我会留下我的答案,因为它也是正确的(只是解决问题的一种选择)。

暂无
暂无

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

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