2015-02-18 2 views
1

Попытка подключить мою собственную систему автоматизации .NET к моему термостату гнезда. У меня возникла проблема десериализации данных JSON, а не всех заполнений в классах. Я не очень разбираюсь в JSON или NEST API, поэтому надеюсь, что я правильно подхожу к этому. Я использую библиотеку JSON от Newtonsoft.Deserializing JSON из Nest API в объекты 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, он показывает класс термостатов, но без дополнительных данных ниже.

Может ли кто-нибудь получить такой подход? Является ли проблема десериализацией вложенного JSON?

Любые помощь или рекомендации наиболее ценятся.

+1

Не уверен, если это поможет, как я не знаю Nest API формат JSON, но Visual Studio будет создавать классы непосредственно из строки Json. Это должно помочь вам правильно подобрать формат. – DavidG

+0

API-интерфейс Nest сложный. Например, устройства могут удерживать все термостаты или защищать. Тогда каждый термостат имеет идентификатор, который может отличаться. См. Клип ниже. Ключ «EGm9FSC4N7xoc1EHo0CiIXTI3byp3LGD» является идентификатором термостата. Если кто-то другой использует это программное обеспечение со своим домом, их термостаты будут иметь разные идентификаторы, если я его правильно пойму. Так что сгенерированные классы не будут работать. Вот почему я использовал подход «Словарь». Возможно, это тоже не лучший подход. «Устройства»: { «термостатов»: { «EGm9FSC4N7xoc1EHo0CiIXTI3byp3LGD»: { –

+0

я был бы соблазн сделать все ваши свойства 'string' тип, получить его работу, а затем положить их обратно в' bool'/'междунар 'и т. д. – DavidG

ответ

3

Вы не показывали JSON, который вы пытаетесь десериализовать, поэтому я собираюсь предположить, что это показано на этом API reference page.

Вещи, чтобы иметь в виду, когда вы создаете ваши классы являются:

  1. Имена свойств в классах должны соответствовать именам свойств в формате JSON на том же уровне, или же быть украшен [JsonProperty] атрибут, чтобы указать имя свойства JSON.
  2. Если имена свойств JSON могут различаться (то есть они являются идентификаторами), в этот момент вы хотите использовать 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; } 
    } 

Fiddle: https://dotnetfiddle.net/7wsRF1

+0

Я попробую сегодня вечером Брайана и посмотрю, как это работает. Спасибо за подробный ответ. –

+0

Я действительно очень хотел увидеть эту работу, которую я отдал до дома и попробовал. Спасибо @ brian-rogers за отличное руководство. Я определенно над его архитектурой. –

+0

Нет проблем; Рад, что ты нашел это полезным. –

Смежные вопросы