簡體   English   中英

為嵌套API在C#中反序列化json

[英]Deserializing json in c# for the nest-api

我正在嘗試使用c#,newtonsoft和.net 3.5來反序列化下面的Devices json結構,但由於“ qxdddh”和“ q0tL6au”是動態生成的名稱,因此無法生成可以工作的代碼。

最終為結構中的每個恆溫器創建一個恆溫器類的列表或數組(在本例中為“ qxdddh”和“ q0tL6au”)。

{
    "thermostats": {
        "qxdddh": {
            "locale": "en-US",
            "temperature_scale": "F",
            "is_using_emergency_heat": false,
            "has_fan": true,
            "software_version": "4.1",
            "has_leaf": true,
            "device_id": "qxdddh",
            "name": "",
            "can_heat": true,
            "can_cool": true,
            "hvac_mode": "heat",
            "target_temperature_c": 12.5,
            "target_temperature_f": 55,
            "target_temperature_high_c": 24.0,
            "target_temperature_high_f": 75,
            "target_temperature_low_c": 20.0,
            "target_temperature_low_f": 68,
            "ambient_temperature_c": 21.0,
            "ambient_temperature_f": 70,
            "away_temperature_high_c": 24.0,
            "away_temperature_high_f": 76,
            "away_temperature_low_c": 12.5,
            "away_temperature_low_f": 55,
            "structure_id": "ryWu-tRQstxux0tYhmZ8ESsrGgDjDQ",
            "fan_timer_active": false,
            "name_long": "Thermostat",
            "is_online": true
        },
        "q0tL6au": {
            "locale": "en-US",
            "temperature_scale": "F",
            "is_using_emergency_heat": false,
            "has_fan": true,
            "software_version": "4.1",
            "has_leaf": true,
            "device_id": "q0tL6au",
            "name": "Den",
            "can_heat": false,
            "can_cool": true,
            "hvac_mode": "off",
            "target_temperature_c": 20.5,
            "target_temperature_f": 69,
            "target_temperature_high_c": 24.0,
            "target_temperature_high_f": 75,
            "target_temperature_low_c": 20.0,
            "target_temperature_low_f": 68,
            "ambient_temperature_c": 23.0,
            "ambient_temperature_f": 73,
            "away_temperature_high_c": 24.0,
            "away_temperature_high_f": 76,
            "away_temperature_low_c": 12.5,
            "away_temperature_low_f": 55,
            "structure_id": "ryWu-tqNu0tYhmZ8ESsrGgDjDQ",
            "fan_timer_active": false,
            "name_long": "Den Thermostat",
            "is_online": true
        }
    }
}

最初的代碼嘗試是

    public class Devices
    {
        public TstatDetails[] thermostats { get; set; }
    }

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

Devices tstats = (Devices) Newtonsoft.Json.JsonConvert.DeserializeObject<Devices>(jsonstring);

產生並帶有以下說明的異常

無法反序列化當前JSON對象(例如{“ name”:“ value”})為類型'NestTest.NestOAuth2 + TstatDetails []',因為該類型需要JSON數組(例如[1,2,3])才能正確反序列化。

要解決此錯誤,可以將JSON更改為JSON數組(例如[1,2,3]),也可以更改反序列化類型,使其成為普通的.NET類型(例如,不像整數這樣的原始類型,也不像這樣的集合類型)數組或列表),可以從JSON對象反序列化。 還可以將JsonObjectAttribute添加到類型中,以強制其從JSON對象反序列化。

我理解錯誤(我認為),但是對於C#來說還很陌生,因此不確定如何針對這種情況進行糾正。

只需將Devices類更改為使用Dictionary<,>而不是數組即可:

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

JSON.NET將JSON中的thermostats對象的每個屬性解釋為字典中的一個條目,並適當地填充它。 (您的調用代碼保持完全相同。)

然后,您將通過ID獲得所有恆溫器。 例如:

TstatDetails details = tstats["qxdddh"];

一旦可行,我強烈建議您嘗試使所有屬性名稱更加傳統:)

您的Json對象應該是一個數組,而不僅僅是一個對象。

它基本上應該用[ .... ] (在其中肯定可以有多個對象 )包裝,而不要用{ ... }包裝。

它可能看起來類似於:

[
        {
            "locale": "en-US",
            "temperature_scale": "F",
            "is_using_emergency_heat": false,
            ...
        },
        {
            "locale": "en-US",
            "temperature_scale": "F",
            "is_using_emergency_heat": false,
            ...
        }
]

編輯

好吧,我無法與The Skeet競爭。 但是我會留下我的答案,因為它也是正確的(只是解決問題的一種選擇)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM