Комментарии 41
А зачем вам промежуточный JObject
, если можно прекрасно десериализовывать сразу в нужный тип? Не говоря уже о том, что не надо считывать ответ в строку, можно делать десериализацию из потока, да и WebClient
тоже использовать не нужно?
Проще говоря, весь нужный код сводится к
await (await httpClient.GetAsync(uri)).EnsureSuccessStatusCode().Content.ReadAsAsync<T>();
Я заменил webClient на httpClient, в остальном же я, пожалуй, оставлю все как есть.
Если вам требуется JObject "для понимания происходящего" — значит у вас неправильное понимание происходящего...
Скажите, вы думаете, что при десериализации объекта из потока (через JsonSerializer.Deserialize
) где-то фигурирует JObject
?
И для сериализации они тоже вовсе не обязательны.
Насколько я понимаю, они нужны для сериализации
Нет, не нужны.
мое их использование не совсем по назначению.
Именно. Что возвращает нас к идее о том, что понимать происходящее через JObject
, который нигде для этого "происходящего" не используется — странно.
Спецификация JSON, очевидно.
Но вообще, эти понятия имеют вполне прямые соответствия в .net — словарь, массив и примитивное значение.
JObject, также как и промежуточные строки мне нужны для понимания происходящего.
Так вы определитесь, ваша статья — она про работу с библиотекой или про то, как вы понимаете происходящее? Потому что работать с этой библиотекой так, как вы показываете, не надо.
Зачем вообще писать:
…
Никогда не угадаешь, кто прочитает ваш пост. Часто это те, кто разбирается в вопросе на голову лучше вас. Фидбэк от таких людей — возможно, самое ценное, что вы приобретете на Хабре.
…
Мой вопрос не в том, что вы приобретаете от этого поста. Мой вопрос в том, что аудитория хабра от него приобретает.
www.newtonsoft.com/json/help/html/Performance.htm
Еще удобно генерировать DTO классы из json с помощью сервиса app.quicktype.io
ещё очень рано отказываться в сторону System.Text.Json
Вместо DTO можно использовать dynamic
:
string json = "{\"name\": \"Johny\"}";
dynamic obj = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(json);
Console.WriteLine($"Name = {obj.name}");
Сходил по ссылкам и хотел, было, написать, что ещё 4 года назад API этого сайтика был кем-то реализован на C# и притом уже с HttpClient и async'ами, но потом посмотрел в тот код и… Пожалуй, лучше похвалить автора этой статьи за попытку. Довольно наивную (выглядит, будто сильно далёкий от .net человек попытался что-то написать по статьям десятилетней давности), но зато честно самостоятельную.
По сути:
- async/await нужен. уже даже public static async Task Main(string[] args) можно
- WebClient забыть в пользу HttpClient (по большей части из-за п1, впрочем).
- Промежуточные JObject для парсинга в объект не нужны. Его назначение как раз наоборот — не собирая конечную модель работать просто с json-деревом. Дада, тот самый JsonConvert.DeserializeObject<>(), на который уже выше указали
- JSON — не протокол. Это разметка, нотация, формат если хочешь.
- Ну и да, System.Text.Json ещё далековат от полноценной продакш-реди замены newtonsoft'у, но всё ж для таких простых вещей можно и на него посмотреть (кстати, есть ещё и JsonReader — тоже классная штука).
Что же касается промежуточных string, JObject и т.д., то они были нужны мне для понимания внутренних процессов. Все же статья не о том, как написать максимально компактный код.
JsonConvert.DeserializeObject<>() будет во второй части.
В вашем случае, это объект WebClient, т.е. нужно было обернуть его создание в конструкцию using или (для последних версий C#) написать
using var wb = new WebClient();
В общем, статья больше похожа на вредный совет, как писать не нужно.
Вообще-то нужно, если только вы не собираетесь ограничивать количество одновременных запросов до одного.
А можно подробнее про утечку ресурсов? Откуда они вообще возьмутся, чтобы утекать?
HttpClient is intended to be instantiated once and re-used throughout the life of an application. Instantiating an HttpClient class for every request will exhaust the number of sockets available under heavy loads.
Ну и про один запрос оттуда же
The HttpClient class instance acts as a session to send HTTP requests. An HttpClient instance is a collection of settings applied to all requests executed by that instance. In addition, every HttpClient instance uses its own connection pool, isolating its requests from requests executed by other HttpClient instances.
В реальности, мне писали, что получали SocketException, у нас было веселее — приложение чем дольше работало, тем больше процессора использовало. Т.е. после пары недель работы 100%. А при подключении к нему отладчика — всё сбрасывалось и опять типа норма. Приятного анализа, блин.
Да, и работает это именно под Core 2.2 и выше. В более старых версиях — используется другая реализация, а в большом .NET — тот же HttpWebRequest, который не страдает этой проблемой.
Да, я её читал, но именно утечки ресурсов я там не увидел, только длинные TIME_WAIT.
(del, перепутал)
Для биндинга свойств удобно использовать [JsonProperty(PropertyName = «jsonBindingName»)]
Работа с библиотекой Newtonsoft.Json на реальном примере. Часть 1