Веб-версияОткрыть в Telegram

ПостДень 2779. #ЧтоНовенького #NET11

9 сентября 2026
.
.NET Разработчик
Ссылка
нажмите — покажем
День 2779. #ЧтоНовенького #NET11 Потоковая Передача JSON в .NET 11. Окончание Начало JSON-строки: один объект на строку JSON-строки (или NDJSON - Newline Delimited JSON) — формат, который уже используется большинством инструментов потоковой обработки данных — одно значение JSON на строку, разделённые символом \n: {"Id":1,"Total":42.0} {"Id":2,"Total":19.5} {"Id":3,"Total":88.25} Каждая строка представляет собой полный, независимый JSON-документ. Потребитель читает строку, разбирает её, обрабатывает и забывает о ней. Если соединение обрывается после второй строки, первые две строки остаются действительными и пригодными для использования. Вы можете добавить четвёртую строку в файл, не затрагивая первые три. Конвейеры обработки, логи, загрузчики данных, потоки событий используют этот формат. В .NET 11 System.Text.Json может создавать его напрямую. Новые перегрузки JsonSerializer.SerializeAsyncEnumerable принимают флаг topLevelValues: using System.Text; using System.Text.Json; static async IAsyncEnumerable<Reading> GetReadings() { yield return new("sensor-1", 21.5); yield return new("sensor-2", 22.0); } await using var stream = new MemoryStream(); await JsonSerializer.SerializeAsyncEnumerable( stream, GetReadings(), topLevelValues: true); Console.WriteLine( Encoding.UTF8.GetString(stream.ToArray())); // {"Id":"sensor-1","Value":21.5} // {"Id":"sensor-2","Value":22} public sealed record Reading(string Id, double Value); При использовании topLevelValues: true отсутствуют открывающая и закрывающая квадратные скобки и запятые между элементами. Каждый элемент сериализуется и сопровождается переводом строки. Формат также игнорирует WriteIndented, поэтому каждый объект остается на отдельной строке. Потоковая передача NDJSON из конечной точки В ASP.NET Core результат по умолчанию сериализуется в JSON-массив, поэтому для отправки JSON-строк нужно самостоятельно записывать данные в поток ответа: app.MapGet("/orders/export", (OrderService service, HttpResponse response, CancellationToken ct) => { response.ContentType = "application/x-ndjson"; return JsonSerializer.SerializeAsyncEnumerable( response.Body, service.GetAllAsyncStream(ct), topLevelValues: true); }); SerializeAsyncEnumerable возвращает Task, поэтому конечная точка просто возвращает его. Заказы поступают из БД через сериализатор по одному. Память остаётся неизменной независимо от того, экспортируется 100 строк или 10 миллионов. Используйте тип содержимого application/x-ndjson (или application/jsonl), чтобы клиенты знали, что они получают, вместо того чтобы предполагать наличие единого массива. Чтение NDJSON Чтение работает в любой версии .NET, т.к. строка представляет собой обычный JSON: using var reader = new StreamReader(stream); string? line; while ((line = await reader.ReadLineAsync()) is not null) { if (line.Length == 0) continue; var reading = JsonSerializer.Deserialize<Reading>(line)!; await ProcessAsync(reading); } Вы обрабатываете каждую запись по мере её поступления и не создаёте большую коллекцию. Когда использовать? Когда данные большие или неопределённого размера: экспорт большой таблицы, возврат длинного отчёта, подача данных в конвейер обработки или запись лога или файла событий с возможностью добавления. Формат особенно эффективен, когда потребитель обрабатывает записи по одной и когда разорванное соединение должно оставлять после себя действительные частичные данные. Небольшие ответы прекрасно поместятся в память, а обычный JSON-массив браузеры и большинство HTTP-клиентов ожидают по умолчанию. Переход на JSON-строки в этом случае только усложнит обработку ответа без каких-либо преимуществ. FAQ 1. В чем разница между JSON-строками и NDJSON? Это один и тот же формат. "NDJSON" (Newline Delimited JSON) и "JSON Lines" (JSONL) — два его названия, а application/x-ndjson — это тип содержимого, который вы будете встречать чаще всего. 2. Загружает ли SerializeAsyncEnumerable всю коллекцию в память? Нет. Он перебирает элементы IAsyncEnumerable<T> по одному, сериализует каждый и записывает его в поток вывода, прежде чем перейти к следующему. Это обеспечивает стабильность использованной памяти независимо от количества передаваемых элементов. 3. Нужен ли NDJSON для потоковой передачи, или достаточно IAsyncEnumerable? Возвращение IAsyncEnumerable<T> уже обеспечивает потоковую передачу JSON-массива без буферизации, поэтому управление памятью происходит в любом случае. JSON-строки добавляют преимущества формата: каждая запись является независимой, частичный вывод при разрыве соединения всё равно валиден, и можно дописывать данные в файл. 4. Могут ли браузеры читать ответ NDJSON? Автоматически – нет. Если используется await res.json() — он ожидает один JSON-документ. Браузер должен читать поток ответа и разделять его по символам новой строки, самостоятельно разбирая каждую строку. Для стандартного запроса данных из браузера обычный массив проще; JSON-строки следует использовать для конвейеров обработки и экспорта больших объёмов данных. Источник: https://thecodeman.net/posts/streaming-json-in-dotnet-with-json-lines
15 · 1.6K ·

Рядом в ленте

..NET РазработчикДень 2777. #ЗаметкиНаПолях Конечные Точки в ASP.NET Core не Имеют Таймаута ASP.NET Core по умолчанию не применяет таймаут приложения к входящим запросам. Встрое..NET РазработчикДень 2778. #ЗаметкиНаПолях Потоковая Передача JSON в .NET. Начало Допустим, у вас есть конечная точка, которая возвращает список: все заказы за последний кварта
это сообщение
..NET РазработчикДень 2780. #ЧтоНовенького #VS Избегаем Путаницы при Переключении Между Окнами Visual Studio Если вы запускаете несколько экземпляров Visual Studio одновременно ..NET РазработчикДень 2781. #ЗаметкиНаПолях Паттерн «Производитель-потребитель» c System.Threading.Channels. Начало Представим эндпоинт, принимающий файлы, изменяющий их размер
..NET Разработчик.NET Разработчик@NetDeveloperDiary · канал · Технологии
6 750подписчиков1 347средний охват поста
Лента площадки Открыть в Telegram

Открытая публичная лента из поискового индекса ChatCrawler — «Google по публичному Telegram»; обновляется по мере обхода площадки. Время — UTC.

Только публичный контент, официальный API Telegram. О проекте · Вопросы · Чего мы не делаем · Убрать страницу из выдачи · Каталог · Поиск · Как мы считаем