将 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 时要记住的事情是:

  1. 你的 classes 中的 属性 名称需要与 JSON 中的 属性 名称在同一级别匹配,否则用 [JsonProperty] 属性指定 JSON 属性 名称。
  2. 其中 JSON 属性 名称可以不同(即它们是 ID),此时您要使用 Dictionary<string, T>,其中 T 是目标对象类型。
  3. 如果您对特定数据不感兴趣,您可以简单地从 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