尝试将我的自定义.NET自动化系统连接到我的Nest恒温器。我在反序列化JSON数据和不是所有填充到类中时遇到了问题。我对JSON或NEST API不是很精通,所以我希望我能正确地处理这一问题。我正在使用Newtonsoft的JSON库。
我从顶部开始,创建了一个表示所有元数据的类。
public class All
{
public Dictionary<string, Devices> devices { get; set; }
public Dictionary<string, Structures> structures { get; set; }
}
然后我创建了结构类
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; }
}
最后是恒温器细节
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; }
}
一旦我对All元数据进行了API调用并返回JSON,我就尝试使用进行反序列化
Dim deserializedProduct As Nest.All = Newtonsoft.Json.JsonConvert.DeserializeObject(Of Nest.All)(rawresp)
它没有抛出任何错误,并且似乎处理得很好。就我而言,我只有一个恒温器。运行后,我看到deserializedProduct.devices包含1,deserialize.structures包含1。
如果我看反序列化.structures(0),它有structure键,值显示为空的Nest.structure对象,这意味着它没有属性。
如果我查看反序列化的Product.devices,它显示的是恒温器类,但下面没有其他数据。
有人能让这种方法奏效吗?反序列化嵌套JSON有问题吗?
非常感谢您的帮助或指导。
您没有显示您试图反序列化的JSON,所以我假设这就是API参考页上显示的内容。
创建类时需要记住的是:
- 类中的属性名称需要与JSON中相同级别的属性名称匹配,或者使用
[JsonProperty]
属性进行装饰以指定JSON属性名称 - 在JSON属性名称可能不同的情况下(即它们是ID),此时您需要使用
Dictionary<string, T>
,其中T
是目标对象类型 - 如果您对某个特定的数据段不感兴趣,您可以简单地从类中省略该属性,默认情况下它将被忽略
考虑到这一切,你并不遥远;您似乎只是有太多级别的字典,因此生成的结构与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; }
}
Fiddle:https://dotnetfiddle.net/7wsRF1