Задача: получить значение "lastPriceProtected".
С мопощью ClientWebSocket получаю json, он различный:
по этому однозначно получить значение "lastPriceProtected" не получается так как в первой строке данного параметра нет. т.е. как бы я не формировал поиск поля постоянно получаю исключение: "System.NullReferenceException: "Ссылка на объект не указывает на экземпляр объекта.""
======================================================================= после чтения документации и нескольких попыток получил рабочий код, спасибо всем кто помогал.
if (o1["data"] != null) проверка нужна чтобы не получать исключения.
2 ответа 2
Советую вам создать полноценную структуру данных, некий класс, где будут все возможные значения из вашего JSON .
То есть, возьмем 2-ой JSON и сделаем два класса:
Как можно заметить, тут имеются все возможные значения приведенные в красивый вид с красивыми именами.
Далее нам надо десериализовать данные:
Все, можно работать. Все данные, которые имеются в JSON — будут занесены в переменные, а те, которые пустые — будут иметь стандартные значения (то есть null , 0 , false и т.д.). Если не хотим путаться и не заполненные данные хотите получить в NULL значение, то можете добавить знак ? после типа (к примеру public double LastPriceProtected < get; set; >меняем на public double? LastPriceProtected < get; set; >).
Ну теперь простейший вывод:
На выходе получим 0 , либо значение (в вашем случае это 8569,7146 ).
По поводу минимализма и практичности.
1. Использование JObject :
Маленькое приложение, где мы выводим различные данные (как в основном "теле" программы, так и в другом классе):
К примеру на сервере изменилась структура, все данные переименовались. Что делать? Выход — искать где крашется приложение и руками изменять все значения.
Минусы такого подхода в том, что вы не получите ошибку, пока не вызовите эти данные. То есть вы можете что то упустить при редактирование, да и кода править придется много.
Плюсы такого подхода:
- Не нужна структура классов.
- Мы не знаем имена, которые нам доступны, забудем — беда..
- Трудно редактировать в коде.
- Если что то поменялось на сервер, то мы не узнаем это, пока не вызовем. То есть нам трудно будет отловить все переменные, можем где то забыть переименовать и среда разработки нам об этом не скажет.
- Не очень понятные имена, зачастую сервера дают значения вида o , h .
2. Использование Структуры классов :
Точно такая же задача, все точно такое же, но с классами:
Что имеем? Если сервер поменяет структуру, то нам достаточно поменять пару строк в нашем классе, либо вовсе с помощью [JsonProperty(". ")] мы можем указать имя переменной и нечего не трогать.
Плюсы такого подхода:
- Тип, мы его сразу знаем, не надо сто раз конвертировать.
- Если поменяются данные, то не потеряетесь при изменение, среда разработки подскажет что и где не так.
- Удобные имена.
- Удобное использование.
- Знаем все доступные переменные, не надо вспоминать имя.
- Ну, может быть большая "портянка" из структуры классов, но ИМХО, положил в файлик .cs да забыл.
В предидущих статьях мы показали, как программа написанная на C# может обмениваться данными с использованием интерфейсов ETHERNET и последовательный порт. При обмене данными с устройствами, часто возникает необходимость в преобразовании произвольных данных в поток байт. А так-же в обратной операции- преобразовании потока байт в исходные данные. Такие операции называются сериализация и десериализация.
Сериализация — это процесс перевода структуры данных в последовательность битов, или же в другую структуру данных, которую удобно хранить, передавать.
Десериализация — это обратный процесс. Процесс преобразования сериализованных данных в структуру данных.
Рассмотрим эти действия на примере формата JSON.
Сериализация
В данном примере мы рассмотрим библиотеку «Newtonsoft.Json» для работы с JSON. Почему её? Потому что она удобная.
Для начала её нужно установить. Проще всего это сделать с помощью консоли диспетчера пакетов NuGet. Выбираем пункт меню
Средства->Диспетчер пакетов NuGet->Консоль диспетчера пакетов.
В консоли нужно выполнить команду:
Ход выполнения установки компонента:
Теперь можно приступить к коду.
Для начала нужно добавить NameSpace библиотеки в код. Для этого добавим в using следующую строку:
Теперь нужно описать класс, который будем сериализовать и десериализовать:
Теперь добавим несколько устройств:
Теперь сериализуем этот класс и выведем на TextBox:
В результате чего мы должны получить такую строку на выходе:
Десериализация
Теперь нужно эту строку десериализовать обратно в класс. Для этого, естественно, должен быть объявлен соответствующий класс, иначе программа не сможет ничего десериализовать.
Сам код десериализации следующий:
Теперь выведем на экран содержимое десериализованного JSON’а:
На экран должно вывестись следующий текст:
Как видите — с JSON очень удобно работать. Но есть одна маленькая хитрость, которая сильно упростит вашу жизнь при десериализации. Чтобы вам вручную не создавать огромные классы анализируя пример JSON’а, который вам возвращает API — можно его сгенерировать автоматически. В этом вам поможет сайт Json2CSharp. Просто вставьте в него строку с JSON, которую вы получили из API и он сгенерирует вам необходимые классы. Основной класс будет всегда RootObject (в примере был myDevices), но никто не мешает вам его переименовать в нужный.
Over 100 code samples covering Json.NET’s most commonly used functionality.
Serializing JSON — Serializing and deserializing JSON, serializer settings and serialization attributes
LINQ to JSON — Parsing, querying, modifying and writing JSON
JSON Schema — Loading schemas and validating JSON. Note that JSON Schema validation has been moved to its own package. See https://www.newtonsoft.com/jsonschema for more details.
Converting XML — Converting JSON to XML and XML to JSON
BSON — Serializing and deserializing BSON
Reading and Writing JSON — Reading JSON with JsonTextReader, writing JSON with JsonTextWriter