2015-02-18 118 views
1

試圖將我的自定義.NET自動化系統連接到我的Nest Thermostat。我有一個反序列化JSON數據的問題,而不是全部填充到類中。我對JSON或NEST API不是很熟悉,所以我希望我能正確地處理這個問題。我正在使用Newtonsoft的JSON庫。將Nest API中的JSON反序列化爲C#對象

我從頂部開始創建一個代表所有元數據的類。

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; } 
} 

最後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

不知道這會幫助,因爲我不知道鳥巢API JSON格式,但Visual Studio將直接創建類從Json字符串。這應該有助於您正確匹配格式。 – DavidG 2015-02-18 00:07:02

+0

Nest API很棘手。例如,設備可以容納所有恆溫器或保護裝置。然後每個恆溫器都有一個可能不同的標識符。看下面的剪輯。 「EGm9FSC4N7xoc1EHo0CiIXTI3byp3LGD」鍵是一個恆溫器ID。如果其他人在家中使用該軟件,如果我正確理解,他們的恆溫器將具有不同的ID。所以生成的類不起作用。這就是我使用Dictionary方法的原因。也許這也不是最好的方法。 「設備」:{ 「恆溫器」:{ 「EGm9FSC4N7xoc1EHo0CiIXTI3byp3LGD」:{ – 2015-02-18 01:18:51

+0

我會受到誘惑,使你所有的屬性'string'類型,得到它的工作,然後把他們帶回'bool' /'INT '等 – DavidG 2015-02-18 01:39:55

回答

3

你沒有顯示你想要反序列化的JSON,所以我會假設它是這個API reference page上顯示的內容。

要記住當你創建類的事情是:

  1. 類中的屬性名稱必須在同一級別相匹配的JSON屬性名稱,否則將有[JsonProperty]裝飾屬性來指定JSON屬性名稱。
  2. 如果JSON屬性名稱可能會有所不同(即它們是ID),那麼您希望使用Dictionary<string, T>,其中T是目標對象類型。
  3. 如果您對某一段數據不感興趣,您可以簡單地從您的課程中省略該屬性,並且默認情況下它將被忽略。

考慮到這一切,你不是太遙遠;看起來你只是有太多的字典級別,所以產生的結構與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

+0

我今晚會試試這個Brian,看看它是如何工作的。感謝您的詳細回覆。 – 2015-02-18 16:28:24

+0

我實際上非常渴望看到這些我遠程回家並嘗試過的作品。感謝@布萊恩羅傑斯的偉大指導。我絕對是在架構它。 – 2015-02-18 17:24:24

+0

沒問題;很高興你發現它有幫助。 – 2015-02-18 20:35:56