Перейти к содержимому

Newtonsoft json что это

  • автор:

О том, как использовать Json в C#

JSON — простой, основанный на использовании текста, способ хранить и передавать структурированные данные. Сегодня рассмотри, как попросить Json у сайта и что с ним делать?

Сначала несколько определений, позаимствованных мною с просторов Интернета:

Сериализация — это процесс перевода структуры данных в последовательность битов, или же в другую структуру данных, которую удобно хранить, передавать (этот процесс в статье подробно мы не будем рассматривать)

Десериализация — это обратный процесс. Процесс преобразования сериализованных данных в структуру данных.

Теперь рассмотрим практический пример:

На первом этапе в студии из NuGet скачиваем — Newtonsoft.Json, указываем в поиске — Json, находим — Newtonsoft.Json (его мы и будем использовать)

Затем прописываем — using Newtonsoft.Json.Linq;

Теперь нам необходимо найти страницу, с которой берем json (то есть берем страницу, где только json, и дальше выбираем один из вариантов):

  1. Для тех, кто старается сделать быстро: копируем весь текст json со страницы, переходим на специальный сайт, который экономит наше время тем, что строит за нас классы (например — http://json2csharp.com/#), вставляем json на этом сайте. И одним нажатием на кнопку – получаем результат (его и копируем в студию).

Как можно улучшить выгрузку:

  • Проверить страницы с json и дописать переменные, если их не хватает
  • Проверить название классов (часто встречается, что несколько классов с одним именем, если разные страницы разбираем в одной программе)

2. Для тех, кто желает погрузиться в разработку:

создаете открытый класс

public class Data

Делаете описание класса с наймингами, как в Json и получаем то же самое, что и в первом случае:

  < public int a < get; set; >public string b < get; set; >public double c < get; set; >public List d < get; set; >>

3. Если информации не много, то классы можно не использовать.

Дальше получаем текст и вставляем его в объект jsona:

JObject jObject = JObject.Parse(Text);

1. Если выбрали 3, то можно указать путь и конвертнуть в тот тип данных, который нужен:

Convert.ToInt16(jObject["data"]["data2"])

2. Если выбрали 1 или 2 вариант, то мы производим десериализацию json в list,

List list = jObject.ToObject>(); Кстати, тут тоже можно указывать путь: jObject["data"]["data2"].ToObject>(); 

Вот такими методами мы «подружили» Json и C#.

Что такое » newtonsoft.json.dll » ?

В нашей базе содержится 1611 разных файлов с именем newtonsoft.json.dll . You can also check most distributed file variants with name newtonsoft.json.dll. Чаще всего эти файлы принадлежат продукту Json.NET. Наиболее частый разработчик — компания Newtonsoft. Самое частое описание этих файлов — Json.NET .NET 2.0. Этот файл — динамически подключаемая библиотека. Такая библиотека может загружаться и выполняться любым работающим процессом.

Подробности о наиболее часто используемом файле с именем «newtonsoft.json.dll»

Продукт: Json.NET Компания: Newtonsoft Описание: Json.NET .NET 2.0 Версия: 4.5.9.15308 MD5: aa37f07c42cf858455fe32fe9c68e5c7 SHA1: 2dda873dc21db27a238be0557ddf47d4ba9f3bd7 SHA256: 2f24133eaec5e2475c24ccf813d92822be233a3e3872529a9c7296ad7fa3e823 Размер: 399280 Папка: %USERPROFILE%\AppData\Local\Facebook\Messenger\2.1.4814.0 ОС: Windows 7 Частота: Высокая Цифровая подпись: Facebook, Inc.

Проверьте свой ПК с помощью нашей бесплатной программы

Icon

System Explorer это наша бесплатная, удостоенная наград программа для быстрой проверки всех работающих процессов с помощью нашей базы данных. Эта программа поможет вам держать систему под контролем.

Библиотека «newtonsoft.json.dll» безопасная или опасная?

Последний новый вариант файла «newtonsoft.json.dll» был обнаружен 3928 дн. назад. В нашей базе содержится 120 шт. вариантов файла «newtonsoft.json.dll» с окончательной оценкой Безопасный и ноль вариантов с окончательной оценкой Опасный . Окончательные оценки основаны на комментариях, дате обнаружения, частоте инцидентов и результатах антивирусных проверок.

Библиотека с именем «newtonsoft.json.dll» может быть безопасным или опасным. Чтобы дать правильную оценку, вы должны определить больше атрибутов файла. Самый простой способ это сделать — воспользоваться нашей бесплатной утилитой для проверки файлов посредством нашей базы данных. Эта утилита содержит множество функций для контролирования вашего ПК и потребляет минимум системных ресурсов.
Щёлкните здесь, чтобы загрузить System Explorer.

Комментарии пользователей для «newtonsoft.json.dll»

У нас пока нет комментариев пользователей к файлам с именем «newtonsoft.json.dll».

Добавить комментарий для «newtonsoft.json.dll»

Для добавления комментария требуется дополнительная информация об этом файле. Если вам известны размер, контрольные суммы md5/sha1/sha256 или другие атрибуты файла, который вы хотите прокомментировать, то вы можете воспользоваться расширенным поиском на главной странице .

Если подробности о файле вам неизвестны, вы можете быстро проверить этот файл с помощью нашей бесплатной утилиты. Загрузить System Explorer.

Проверьте свой ПК с помощью нашей бесплатной программы

System Explorer это наша бесплатная, удостоенная наград программа для быстрой проверки всех работающих процессов с помощью нашей базы данных. Эта программа поможет вам держать систему под контролем. Программа действительно бесплатная, без рекламы и дополнительных включений, она доступна в виде установщика и как переносное приложение. Её рекомендуют много пользователей.

Работа с библиотекой Newtonsoft.Json на реальном примере. Часть 1

Если Вы читаете данную статью, значит, скорее всего, Вы в курсе что такое JSON и картинка ниже Вам знакома. Но в любом случае советую посетить эту страничку, если Вы там еще не были, а так же перед прочтением желательно ознакомиться с общими принципами работы с протоколом JSON на языке C#, например по этой ссылке.

Хочу отметить, что данная заметка не претендует на какую-то полноту раскрытия темы. Цель данного текста – структурировать и сохранить те наработки, которые я использовал при работе с библиотекой Newtonsoft.Json.

Постановка задачи

По большому счету, в рамках статьи не так важно каким образом были получены исходные данные, для парсинга, однако данное пояснение наверняка облегчит восприятие материала. Итак, основная задача состоит в том, чтобы реализовать функции API криптобиржи EXMO. Для простоты будем в основном работать с Публичным интерфейсом (Public API). В данном случае запрос информации будет выглядеть как обычный адрес странички сайта. Для отправки запросов используется класс WebClient пространства имен System.Net:

var wb = new WebClient(); string request = "https://api.exmo.com/v1/trades/?pair=BTC_USD"; string answer = wb.DownloadString(request); 

Результат работы данной программы можно увидеть пройдя по ссылке https://api.exmo.com/v1/trades/?pair=BTC_USD. Если загрузить эти данные в JSON C# Class Generator, нам будет предложена следующая структура класса для десериализации:

 public class BTCUSD < public int trade_id < get; set; >public string type < get; set; >public string quantity < get; set; >public string price < get; set; >public string amount < get; set; >public int date < get; set; >> public class RootObject < public ListBTC_USD < get; set; >> 

Надо отметить, что сама функция “trades” криптобиржи позволяет запрашивать информацию сразу по нескольким валютным парам. И в случае запроса

string request = "https://api.exmo.com/v1/trades/?pair=BTC_USD,ETH_USD";

Структура класса будет выглядеть уже следующим образом:

 public class BTCUSD < public int trade_id < get; set; >public string type < get; set; >public string quantity < get; set; >public string price < get; set; >public string amount < get; set; >public int date < get; set; >> public class ETHUSD < public int trade_id < get; set; >public string type < get; set; >public string quantity < get; set; >public string price < get; set; >public string amount < get; set; >public int date < get; set; >> public class RootObject < public ListBTC_USD < get; set; >public List ETH_USD < get; set; >> 

Очевидно, что для каждой комбинации валютных пар классы не подготовишь, а значит нужно как-то выкручиваться.

Как делать не нужно.

Удивительно, но хороших статей по работе с протоколом JSON в русскоязычном интернете найти практически невозможно. Как следствие, те реализации EXMO API, которые можно найти на GitHub`е так или иначе содержат манипуляции с исходной структурой данных с использованием spit`ов, trim`ов и тому подобных непотребств.

Надо признать, что я то же сначала изобрел велосипед и реализовал парсинг самостоятельно. Несмотря на то, что код абсолютно рабочий, это отличный пример как НЕЛЬЗЯ делать.

LinkedList loi = new LinkedList(); try < string[] json = answer.Split(new char[] < '' >); foreach (var item in json) < if (item.Length >20) < string[] trade = item.Split(new char[] < ',' >); if (trade.Length > 5) < string t_id = trade[0].Split(new char[] < ':' >)[1].Trim('"'); string t_type = trade[1].Split(new char[] < ':' >)[1].Trim('"'); string t_quantity = trade[2].Split(new char[] < ':' >)[1].Trim('"') .Replace(".", ","); string t_price = trade[3].Split(new char[] < ':' >)[1].Trim('"') .Replace(".", ","); string t_amount = trade[4].Split(new char[] < ':' >)[1].Trim('"') .Replace(".", ","); string t_date_time = trade[5].Split(new char[] < ':' >)[1].Trim('"'); loi.AddLast(new OrderInform(pair, Convert.ToInt32(t_id), t_type, Convert.ToDouble(t_quantity), Convert.ToDouble(t_price), Convert.ToDouble(t_amount), (new DateTime(1970, 1, 1, 0, 0, 0, 0)) .AddSeconds(Convert.ToInt32(t_date_time)))); > > > return loi; > catch (Exception ex) < return new LinkedList(); > 

Объекты JSON (класс JObject)

Объект JSON — неупорядоченный набор пар ключ/значение. Объект начинается с » (закрывающей фигурной скобкой). Каждое имя сопровождается: (двоеточием), пары ключ/значение разделяются запятой.

Из структуры, предложенной нам ранее JSON C# Class Generator`ом видно, что для каждой валютной пары у нас есть 6 постоянных полей. Обернем их в отдельный класс и назовем его Order.

 class Order < public int trade_id < get; set; >public string type < get; set; >public double quantity < get; set; >public double price < get; set; >public double amount < get; set; >public int date < get; set; >> 

Для того, чтобы суметь «выцепить» набор этих полей из динамически меняющейся структуры данных биржи, необходимо поподробней разобраться с типами данных доступными в библиотеке newtosoft.json. А точнее в пространстве имен newtonsoft.json.linq.

Для работы с библиотекой ее необходимо установить.

Чтобы установить библиотеку в Visual Studio можно просто выполнить поиск в NuGet.
Нажимаем правой кнопкой мыши на Решение (Solution) в Обозревателе решений (Solution explorer) и выбираем пункт «Управлением пакетами NuGet для решения. » («Mange NuGet Packages for solution. »).

Далее жмем «Обзор» («Browse») и в строке поиска вводим newtosoft.json. Ставим галочку напротив нашего решения и нажимаем «Установить» («Install»).

Пространство имен newtosoft.json.linq, после установки библиотеки, становится доступно для подключения к проекту:

using Newtonsoft.Json.Linq; 

Для представления данных в newtosoft.json.linq используется абстрактный класс JToken, от которого наследуются классы JValue (для представления простых значений) и JContainer (для представления структур). Структуры в свою очередь могут представлять из себя JArray (массив), JConstructor (конструктор), JObject (объект), либо JProperty (свойство).

В классах JArray и JObject имеется метод Parse, позволяющей преобразовывать JSON данные из обычной строки в соответствующие объекты. Так, если мы воспользуемся методом JObject.Parse(String) для структуры данных функции trades биржи Exmo:

var wb = new WebClient(); string request = "https://api.exmo.com/v1/trades/?pair=BTC_USD,ETH_USD"; string answer = wb.DownloadString(request); JObject jObject = JObject.Parse(answer); 

мы увидим структуру из двух элементов, каждый из которых представляет пару ключ-значение. Ключом в данном случае будет название валютной пары (тип String), а значением — список сделок (тип JToken):

Теперь списки сделок нам доступны по ключам «BTC_USD» и «USD_ETH». Например сделки по валютной паре «BTC_USD»:

Далее нам только останется перевести полученные данные в удобный для работы тип, например List , используя метод ToObject<>():

var wb = new WebClient(); string request = "https://api.exmo.com/v1/trades/?pair=BTC_USD,ETH_USD"; string answer = wb.DownloadString(request); JObject jObject = JObject.Parse(answer); JToken list = jObject["BTC_USD"]; List trades = list.ToObject(); 

либо всю структуру преобразовать в тип Dictionary> :

string request = "https://api.exmo.com/v1/trades/?pair=BTC_USD,ETH_USD"; var wb = new WebClient(); string answer = wb.DownloadString(request); JObject jObject = JObject.Parse(answer); Dictionary> trades = new Dictionary>(); foreach (KeyValuePair obj in jObject) trades.Add(obj.Key, obj.Value.ToObject>()); 

Массивы JSON (класс JArray)

Массив JSON — упорядоченная коллекция значений. Массив начинается с ‘[‘ (открывающей квадратной скобки) и заканчивается ‘]’ (закрывающей квадратной скобкой). Значения разделены запятой.

Как выглядит массив JSON можно увидеть пройдя по ссылке https://api.exmo.com/v1/currency. Если попытаться преобразовать его в объект JObject, так как мы делали с предыдущим запросом:

var wb = new WebClient(); string request = "https://api.exmo.com/v1/currency"; string answer = wb.DownloadString(request); JObject jObject = JObject.Parse(answer); 

мы получим исключение Newtonsoft.Json.JsonReaderException, сообщающее нам, что преобразуемые данные не являются объектом.

Массивы должны быть преобразованы в специальный тип JArray, который, так же как JObject, наследуется от JContainer.

var wb = new WebClient(); string request = "https://api.exmo.com/v1/currency"; string answer = wb.DownloadString(request); JArray jArray = JArray.Parse(answer); 

В случае, когда при парсинге, исходная структура заранее неизвестна, либо требуется возможность обработки обоих типов данных — в качестве типа преобразуемого объекта можно указать JContainer, или же JToken, тогда во время парсинга данные будут неявно преобразованы к нужному типу.

var wb = new WebClient(); string request = "https://api.exmo.com/v1/currency"; string answer = wb.DownloadString(request); JToken jArray = JToken.Parse(answer); // Неявное преобразование в JArray List list = jArray.ToObject(); request = "https://api.exmo.com/v1/trades/?pair=BTC_USD,ETH_USD"; answer = wb.DownloadString(request); JToken jObject = JToken.Parse(answer); // Неявное преобразование в JObject Dictionary> dict = jObject.ToObject>(); 

Значения JSON (класс JValue)

Согласно описанию формата JSON, значение может быть строкой в двойных кавычках, числом, true, false, null, объектом или массивом. Эти структуры могут быть вложенными. В реализации newotnsoft.json значением могут быть только объекты простых типов. Попытка преобразовать объект JArray в объект JValue приведет к исключению «System.InvalidCastException».

В качестве ознакомительного материала по работе с конкретными значениями (класс JValue) в библиотеке newtonsoft.json — хорошо подойдут примеры из документации раз и два.

Пример использования для данных с биржи:

 var wb = new WebClient(); string request = "https://api.exmo.com/v1/currency"; string answer = wb.DownloadString(request); JArray jArray = JArray.Parse(answer); foreach (JValue value in jArray)

Во второй части статьи я более детально опишу возможности подготовки класса для парсинга данных, а также некоторые особенности работы с типом данных DateTime.

Полный текст программы.

using System.Collections.Generic; using System.Net; using Newtonsoft.Json; using Newtonsoft.Json.Linq; namespace JSONObjects < class Order < public int trade_id < get; set; >public string type < get; set; >public double quantity < get; set; >public double price < get; set; >public double amount < get; set; >public int date < get; set; >> class Program < static void Main(string[] args) < var wb = new WebClient(); string request = "https://api.exmo.com/v1/currency"; string answer = wb.DownloadString(request); JToken jArray = JToken.Parse(answer); // Неявное преобразование в JArray Listlist = jArray.ToObject(); request = "https://api.exmo.com/v1/trades/?pair=BTC_USD,ETH_USD"; answer = wb.DownloadString(request); JToken jObject = JToken.Parse(answer); // Неявное преобразование в JObject Dictionary> dict = jObject.ToObject>(); > > > 

Наиболее полную и подробную информацию о библиотеке всегда можно почерпнуть из официальной документации.

Работа с библиотекой Newtonsoft.Json на реальном примере. Часть 2

В первой части статьи был рассмотрен механизм парсинга объектов JSON с динамически изменяющейся структурой. Данные объекты приводились к типам пространства имен newtonsoft.json.linq, и затем преобразовывались в структуры языка C#. В комментариях к первой части было много критики, по большей части обоснованной. Во второй части я постараюсь учесть все замечания и пожелания.

Далее речь пойдет о подготовке классов для более тонкой настройки преобразования данных, но в начале необходимо вернуться к самому парсингу JSON. Напомню в первой части были использованы методы Parse() и ToObject() классов JObject и JArray пространства имен newtonsoft.json.linq:

HttpClient httpClient = new HttpClient(); string request = "https://api.exmo.com/v1/trades/?pair=BTC_USD,ETH_USD"; HttpResponseMessage response = (await httpClient.GetAsync(request)).EnsureSuccessStatusCode(); string responseBody = await response.Content.ReadAsStringAsync(); JObject jObject = JObject.Parse(responseBody); Dictionary> dict = jObject.ToObject>(); 

Необходимо отметить, что в пространстве имен newtonsof.json в классе JsonConvert есть статический метод DeserializeObject<>, позволяющий преобразовывать строки напрямую в структуры C#, соответствующие объектам и массивам нотации JSON:

Dictionary> JsonObject = JsonConvert.DeserializeObject>(responseBody); List Json_Array = JsonConvert.DeserializeObject(responseBody); 

И в дальнейшем в статье будет использован именно этот метод, поэтому в программу нужно добавить using newtonsoft.json.

Кроме того, есть возможность еще больше сократить количество промежуточных преобразований — после установки библиотеки Microsoft.AspNet.WebApi.Client (так же доступна через NuGet), данные можно будет парсить прямо из потока используя метод ReadAsAsync:

Dictionary> JsonObject = await (await httpClient.GetAsync(request)). EnsureSuccessStatusCode().Content. ReadAsAsync>(); 

За подсказку спасибо lair.

Подготовка класса для преобразования

Вернемся к нашему классу Order:

 class Order < public int trade_id < get; set; >public string type < get; set; >public double quantity < get; set; >public double price < get; set; >public double amount < get; set; >public int date < get; set; >> 

Напомню, он был создан на основе формата, предложенного JSON C# Class Generator`ом. Есть два момента, которые при работе с объектами данного класса могут вызвать сложности.

Первый — в таком виде свойства нашего класса нарушают правила наименования полей. Ну и кроме того, логично для объекта типа Order ожидать что его идентификатор будет называться OrderID (а не traid_id, как происходило в примерах из первой части). Чтобы связать элемент структуры JSON и свойство класса с произвольным именем, необходимо перед свойством добавить атрибут JsonProperty:

 class Order < [JsonProperty("trade_id")] public int OrderID < get; set; >[JsonProperty("type")] public string Type < get; set; >[JsonProperty("quantity")] public double Quantity < get; set; >[JsonProperty("price")] public double Price < get; set; >[JsonProperty("amount")] public double Amount < get; set; >[JsonProperty("date")] public int Date < get; set; >> 

В результате, значение, соответствующее элементу “trade_id”, будет записано в свойство OrderID, “type” в Type и т.д. Так же атрибут JsonProperty необходим для сериализации / десериализации свойств, имеющих модификаторы private или static — по умолчанию такие свойства игнорируются.
В итоге, код для составления списка всех OrderID сделок по валютным парам BTC_USD и ETH_USD, может выглядеть следующим образом:

using HttpClient httpClient = new HttpClient(); string request = "https://api.exmo.com/v1/trades/?pair=BTC_USD,ETH_USD"; string responseBody = await (await httpClient.GetAsync(request)). EnsureSuccessStatusCode(). Content.ReadAsStringAsync(); Dictionary> PairList = JsonConvert.DeserializeObject>(responseBody); List IDs = new List(); foreach (var pair in PairList) foreach (var order in pair.Value) IDs.Add(order.OrderID); 

Вторая сложность при работе с данным классом будет заключаться в свойстве Date. Как можно увидеть, JSON C# Class Generator определил элемент “date” как простое целочисленное число. Но гораздо удобнее было бы, чтобы свойство Date нашего класса имело тип специально созданный для дат — DateTime. Как это сделать — будет описано далее.

Особенности работы с датами

Начальную фразу статьи в документации по newtonsof.json, с описанием работы с датами, можно примерно перевести как “DateTime в JSON — это тяжко”. Проблема заключается в том, что сама спецификация JSON не содержит информации о том, какой синтаксис необходимо применять для описания даты и времени.

Все относительно неплохо, когда дата в JSON строке представлена в текстовом виде и формат представления соответствует одному из трех вариантов: “Майкрософт” (в настоящее время считается устаревшим), “JavaScript” (Unix время) и вариант ISO 8601. Примеры допустимых форматов:

Dictionary d = new Dictionary  < < "date", DateTime.Now >>; string isoDate = JsonConvert.SerializeObject(d); // JsonSerializerSettings microsoftDateFormatSettings = new JsonSerializerSettings < DateFormatHandling = DateFormatHandling.MicrosoftDateFormat >; string microsoftDate = JsonConvert.SerializeObject(d, microsoftDateFormatSettings); // string javascriptDate = JsonConvert.SerializeObject(d, new JavaScriptDateTimeConverter()); //

Однако в случае с биржей Exmo, все немного сложнее. В описании API биржи указано, что дата и время указываются в формате Unix (JavaScript). И, теоретически, добавив к нашему свойству Date класса Order функцию преобразования формата из класса JavaScriptDateTimeConverter(), мы должны получить дату, приведенную к типу DateTime:

 class Order < [JsonProperty("trade_id")] public int OrderID < get; set; >[JsonProperty("type")] public string Type < get; set; >[JsonProperty("quantity")] public double Quantity < get; set; >[JsonProperty("price")] public double Price < get; set; >[JsonProperty("amount")] public double Amount < get; set; >[JsonProperty("date", ItemConverterType = typeof(JavaScriptDateTimeConverter))] public DateTime Date < get; set; >> 

Однако в этом случае, при попытке парсинга данных в переменную типа DateTime появляется уже знакомое по первой части статьи исключение Newtonsoft.Json.JsonReaderException. Происходит это по причине того, что функция преобразования класса JavaScriptDateTimeConverter не умеет конвертировать числовые данные в тип DateTime (это работает только для строк).

Возможный выход из данной ситуации — написать свой собственный класс преобразования форматов. На самом деле такой класс уже есть и его можно использовать, предварительно подключив пространство имен Newtonsoft.Json.Converters (обратите внимание, что обратная функция — конвертирования из DateTime в формат JSON в данном классе не реализована):

 class UnixTimeToDatetimeConverter : DateTimeConverterBase < private static readonly DateTime _epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) < throw new NotImplementedException(); >public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) < if (reader.Value == null) < return null; >return _epoch.AddSeconds(Convert.ToDouble(reader.Value)).ToLocalTime(); > > 

Остается только подключить нашу функцию к свойству Date класса Order. Для этого необходимо использовать атрибут JsonConverter:

 class Order < [JsonProperty("trade_id")] public int OrderID < get; set; >[JsonProperty("type")] public string Type < get; set; >[JsonProperty("quantity")] public double Quantity < get; set; >[JsonProperty("price")] public double Price < get; set; >[JsonProperty("amount")] public double Amount < get; set; >[JsonProperty("date")] [JsonConverter(typeof(UnixTimeToDatetimeConverter))] public DateTime Date < get; set; >> 

Теперь наше свойство Date имеет тип DateTime и мы можем, например, сформировать список сделок, за последние 10 минут:

HttpClient httpClient = new HttpClient(); string request = "https://api.exmo.com/v1/trades/?pair=BTC_USD,ETH_USD"; string responseBody = await (await httpClient.GetAsync(request)). EnsureSuccessStatusCode(). Content.ReadAsStringAsync(); Dictionary> PairList = JsonConvert.DeserializeObject>(responseBody); List Last10minuts = new List(); foreach (var pair in PairList) foreach (var order in pair.Value) if (order.Date > DateTime.Now.AddMinutes(-10)) Last10minuts.Add(order); 

Полный текст программы

using System; using System.Threading.Tasks; using System.Collections.Generic; using System.Net.Http; using Newtonsoft.Json; using Newtonsoft.Json.Converters; using Newtonsoft.Json.Serialization; namespace JSONObjects < class Order < [JsonProperty("pair")] public string Pair < get; set; >[JsonProperty("trade_id")] public int OrderID < get; set; >[JsonProperty("type")] public string Type < get; set; >[JsonProperty("quantity")] public double Quantity < get; set; >[JsonProperty("price")] public double Price < get; set; >[JsonProperty("amount")] public double Amount < get; set; >[JsonProperty("date")] [JsonConverter(typeof(UnixTimeToDatetimeConverter))] public DateTime Date < get; set; >> class UnixTimeToDatetimeConverter : DateTimeConverterBase < private static readonly DateTime _epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) < throw new NotImplementedException(); >public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) < if (reader.Value == null) < return null; >return _epoch.AddSeconds(Convert.ToDouble(reader.Value)).ToLocalTime(); > > class Program < public static async Task Main(string[] args) < using HttpClient httpClient = new HttpClient(); string request = "https://api.exmo.com/v1/trades/?pair=BTC_USD,ETH_USD"; string responseBody = await (await httpClient.GetAsync(request)). EnsureSuccessStatusCode(). Content.ReadAsStringAsync(); Dictionary> PairList = JsonConvert. DeserializeObject>(responseBody); List Last10minuts = new List(); foreach (var pair in PairList) foreach (var order in pair.Value) if (order.Date > DateTime.Now.AddMinutes(-10)) Last10minuts.Add(order); > > > 

Подмена имен элементов JSON

Ранее мы работали с командой trades биржи. Данная команда возвращает объекты со следующими полями:

public class BTCUSD < public int trade_id < get; set; >public string type < get; set; >public string quantity < get; set; >public string price < get; set; >public string amount < get; set; >public int date < get; set; >> 

Команда биржи user_open_orders возвращает очень похожую структуру:

public class BTCUSD < public string order_id < get; set; >public string created < get; set; >public string type < get; set; >public string pair < get; set; >public string quantity < get; set; >public string price < get; set; >public string amount < get; set; >> 

Поэтому имеет смысл адаптировать класс Order, чтобы в него можно было преобразовывать не только данные команды trade, но также и данные команды user_open_orders.

Отличия заключаются в том, что появился новый элемент pair, содержащий название валютной пары, trade_id заменен на order_id (и теперь это строка), а date стала created и тоже является строкой.

Начнем с того, что добавим возможность сохранения полей order_id и created в соответствующие поля OrderID и Date класса Order. Для этого подготовим класс OrderDataContractResolver, в котором будет происходить подмена имен полей для парсинга (потребуются пространства имен System.Reflection и Newtonsoft.Json.Serialization):

 class OrderDataContractResolver : DefaultContractResolver < public static readonly OrderDataContractResolver Instance = new OrderDataContractResolver(); protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) < var property = base.CreateProperty(member, memberSerialization); if (property.DeclaringType == typeof(Order)) < if (property.PropertyName.Equals("trade_id", StringComparison.OrdinalIgnoreCase)) < property.PropertyName = "order_id"; >if (property.PropertyName.Equals("date", StringComparison.OrdinalIgnoreCase)) < property.PropertyName = "created"; >> return property; > > 

Далее этот класс необходимо указать в качестве параметра метода DeserializeObject следующим образом:

Dictionary> PairList = JsonConvert.DeserializeObject>(responseBody, new JsonSerializerSettings < ContractResolver = OrderDataContractResolver.Instance >); 

В результате, такая JSON структура, полученная в качестве ответа на команду user_open_orders:

будет преобразована в такую структуру данных:

Обратите внимание, что для корректной работы программы, тип поля OrderID в классе Order пришлось заменить на string.

Полный текст программы

using System; using System.Threading.Tasks; using System.Collections.Generic; using System.Net.Http; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Newtonsoft.Json.Converters; using Newtonsoft.Json.Serialization; using System.Reflection; namespace JSONObjects < class Order < [JsonProperty("pair")] public string Pair < get; set; >[JsonProperty("trade_id")] public string OrderID < get; set; >[JsonProperty("type")] public string Type < get; set; >[JsonProperty("quantity")] public double Quantity < get; set; >[JsonProperty("price")] public double Price < get; set; >[JsonProperty("amount")] public double Amount < get; set; >[JsonProperty("date")] [JsonConverter(typeof(UnixTimeToDatetimeConverter))] public DateTime Date < get; set; >> class OrderDataContractResolver : DefaultContractResolver < public static readonly OrderDataContractResolver Instance = new OrderDataContractResolver(); protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) < var property = base.CreateProperty(member, memberSerialization); if (property.DeclaringType == typeof(Order)) < if (property.PropertyName.Equals("trade_id", StringComparison.OrdinalIgnoreCase)) < property.PropertyName = "order_id"; >if (property.PropertyName.Equals("date", StringComparison.OrdinalIgnoreCase)) < property.PropertyName = "created"; >> return property; > > class UnixTimeToDatetimeConverter : DateTimeConverterBase < private static readonly DateTime _epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) < throw new NotImplementedException(); >public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) < if (reader.Value == null) < return null; >return _epoch.AddSeconds(Convert.ToDouble(reader.Value)).ToLocalTime(); > > class Program < public static async Task Main(string[] args) < using HttpClient httpClient = new HttpClient(); string request = "https://api.exmo.com/v1/trades/?pair=BTC_USD,ETH_USD"; string responseBody = await (await httpClient.GetAsync(request)). EnsureSuccessStatusCode(). Content.ReadAsStringAsync(); Dictionary> PairList = new Dictionary>(); JObject jObject = JObject.Parse(responseBody); foreach (var pair in jObject) < Listorders = new List(); foreach (var order in pair.Value.ToObject()) < order.Pair = pair.Key; orders.Add(order); >PairList.Add(pair.Key, orders); > responseBody = "<\"BTC_USD\":[<\"order_id\":\"4722868563\"," + "\"created\":\"1577349229\",\"type\":\"sell\"," + "\"pair\":\"BTC_USD\",\"quantity\":\"0.002\"," + "\"price\":\"8362.2\",\"amount\":\"16.7244\">]>"; Dictionary> PairList1 = JsonConvert.DeserializeObject> (responseBody, new JsonSerializerSettings < ContractResolver = OrderDataContractResolver.Instance >); > > > >

Как можно заметить, при вызове команды user_open_orders, ответ содежит поле “pair”, в случае же команды trade информация о валютной паре содержится только в значении ключа. Поэтому придется либо заполнить поле Pair уже после парсинга:

foreach (var pair in PairList) foreach (var order in pair.Value) order.Pair = pair.Key; 

Либо же воспользоваться объектом JObject:

Dictionary> PairList = new Dictionary>(); JObject jObject = JObject.Parse(responseBody); foreach (var pair in jObject) < Listorders = new List(); foreach (var order in pair.Value.ToObject()) < order.Pair = pair.Key; orders.Add(order); >PairList.Add(pair.Key, orders); > 

Что в конечном итоге приведет к созданию следующей структуры данных:

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *