将 Nest API 中的 JSON 反序列化为 C# 对象
Deserializing JSON from Nest API into C# objects
正在尝试将我的自定义 .NET 自动化系统连接到我的 Nest Thermostat。我在反序列化 JSON 数据时遇到问题,并不是所有数据都填充到 classes 中。我不是很熟悉 JSON 或 NEST API 所以我希望我能正确地处理这个问题。我正在使用 Newtonsoft 的 JSON 库。
我从头开始创建了一个代表所有元数据的 class。
public class All
{
public Dictionary<string, Devices> devices { get; set; }
public Dictionary<string, Structures> structures { get; set; }
}
然后我创建了结构 Class
public class Structures
{
public Dictionary<string, Structure> structure { get; set; }
}
和设备class
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,它会显示恒温器 class 但下面没有其他数据。
有没有人能让这种方法奏效?问题是反序列化嵌套 JSON 吗?
非常感谢任何帮助或指导。
你没有显示你试图反序列化的 JSON,所以我假设它就是这个 API reference page 上显示的内容。
创建 classes 时要记住的事情是:
- 你的 classes 中的 属性 名称需要与 JSON 中的 属性 名称在同一级别匹配,否则用
[JsonProperty]
属性指定 JSON 属性 名称。
- 其中 JSON 属性 名称可以不同(即它们是 ID),此时您要使用
Dictionary<string, T>
,其中 T
是目标对象类型。
- 如果您对特定数据不感兴趣,您可以简单地从 class 中省略 属性,默认情况下它将被忽略。
综上所述,你离得不远了;似乎您的词典级别太多,因此生成的结构与 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
正在尝试将我的自定义 .NET 自动化系统连接到我的 Nest Thermostat。我在反序列化 JSON 数据时遇到问题,并不是所有数据都填充到 classes 中。我不是很熟悉 JSON 或 NEST API 所以我希望我能正确地处理这个问题。我正在使用 Newtonsoft 的 JSON 库。
我从头开始创建了一个代表所有元数据的 class。
public class All
{
public Dictionary<string, Devices> devices { get; set; }
public Dictionary<string, Structures> structures { get; set; }
}
然后我创建了结构 Class
public class Structures
{
public Dictionary<string, Structure> structure { get; set; }
}
和设备class
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,它会显示恒温器 class 但下面没有其他数据。
有没有人能让这种方法奏效?问题是反序列化嵌套 JSON 吗?
非常感谢任何帮助或指导。
你没有显示你试图反序列化的 JSON,所以我假设它就是这个 API reference page 上显示的内容。
创建 classes 时要记住的事情是:
- 你的 classes 中的 属性 名称需要与 JSON 中的 属性 名称在同一级别匹配,否则用
[JsonProperty]
属性指定 JSON 属性 名称。 - 其中 JSON 属性 名称可以不同(即它们是 ID),此时您要使用
Dictionary<string, T>
,其中T
是目标对象类型。 - 如果您对特定数据不感兴趣,您可以简单地从 class 中省略 属性,默认情况下它将被忽略。
综上所述,你离得不远了;似乎您的词典级别太多,因此生成的结构与 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