将CSS API中的JSON反序列化为C#对象

时间:2015-02-18 00:01:30

标签: c# vb.net json.net nest-api

尝试将我的自定义.NET自动化系统连接到Nest Thermostat。我有问题反序列化JSON数据而不是所有填充到类中。我不是很熟悉JSON或NEST API,所以我希望我正确地接近这个。我正在使用Newtonsoft的JSON库。

我从顶部开始创建了一个代表所有元数据的类。

public class All
{
    public Dictionary<string, Devices> devices { get; set; }
    public Dictionary<string, Structures> structures { get; set; }
}

然后我创建了Structures Class

public class Structures
{
    public Dictionary<string, Structure> structure { get; set; }
}

和设备类

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

还创建了结构

public class Structure
{
    public string name { get; set; }
    public string country_code { get; set; }
    public string time_zone { get; set; }
    public string away { get; set; }
    public IList<string> thermostats { get; set; }
    public string structure_id { get; set; }
}

和恒温器

public class Thermostats
{
    public Dictionary<string, ThermostatDetails> thermostatdetails { get; set; }
}

最后是Thermostatdetails

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

一旦我为所有元数据调用API并获得JSON,我就会尝试使用

进行反序列化
Dim deserializedProduct As Nest.All = Newtonsoft.Json.JsonConvert.DeserializeObject(Of Nest.All)(rawresp)

它不会抛出任何错误,似乎处理正常。在我的情况下,我只有1个恒温器。运行后,我看到deserializedProduct.devices包含1,deserialize.structures包含1.

如果我查看deserialize.structures(0),它有结构键,值显示为空的Nest.Structure对象,意味着它没有属性。

如果我查看deserializedProduct.devices,它会显示Thermostats类,但下面没有其他数据。

有没有人能够使用这种方法?问题是反序列化嵌套的JSON吗?

非常感谢任何帮助或指导。

1 个答案:

答案 0 :(得分:3)

您没有显示您尝试反序列化的JSON,因此我将假设它是API reference page上显示的内容。

创建课程时要记住的事项是:

  1. 类中的属性名称需要与同一级别的JSON中的属性名称匹配,否则请使用[JsonProperty]属性进行修饰以指定JSON属性名称。
  2. 如果JSON属性名称可以变化(即它们是ID),那么您希望使用Dictionary<string, T>,其中T是目标对象类型。
  3. 如果您对某个特定数据不感兴趣,可以在课程中省略该属性,默认情况下会忽略该属性。
  4. 考虑到这一切,你并没有太远;看起来你只是有太多级别的字典,所以结果结构与JSON不匹配。以下是您需要对设备和结构进行反序列化的所有内容:

        public class All
        {
            public Devices devices { get; set; }
            public Dictionary<string, Structure> structures { get; set; }
        }
    
        public class Devices
        {
            public Dictionary<string, Thermostat> thermostats { get; set; }
        }
    
        public class Structure
        {
            public string name { get; set; }
            public string country_code { get; set; }
            public string time_zone { get; set; }
            public string away { get; set; }
            public IList<string> thermostats { get; set; }
            public string structure_id { get; set; }
        }
    
        public class Thermostat
        {
            public int humidity { get; set; }
            public string locale { get; set; }
            public string temperature_scale { get; set; }
            public bool is_using_emergency_heat { get; set; }
            public bool has_fan { get; set; }
            public string software_version { get; set; }
            public bool has_leaf { get; set; }
            public string device_id { get; set; }
            public string name { get; set; }
            public bool can_heat { get; set; }
            public bool can_cool { get; set; }
            public string hvac_mode { get; set; }
            public double target_temperature_c { get; set; }
            public int target_temperature_f { get; set; }
            public double target_temperature_high_c { get; set; }
            public int target_temperature_high_f { get; set; }
            public double target_temperature_low_c { get; set; }
            public int target_temperature_low_f { get; set; }
            public double ambient_temperature_c { get; set; }
            public int ambient_temperature_f { get; set; }
            public double away_temperature_high_c { get; set; }
            public int away_temperature_high_f { get; set; }
            public double away_temperature_low_c { get; set; }
            public int away_temperature_low_f { get; set; }
            public string structure_id { get; set; }
            public bool fan_timer_active { get; set; }
            public string name_long { get; set; }
            public bool is_online { get; set; }
            public DateTime last_connection { get; set; }
        }
    

    小提琴:https://dotnetfiddle.net/7wsRF1