Как десериализовать json c

от admin

# Getting Started: Json with C#

The following topic will introduce a way to work with Json using C# language and concepts of Serialization and Deserialization.

# Simple Json Example

If you are new into Json, here is an exemplified tutorial

# First things First: Library to work with Json

To work with Json using C#, it is need to use Newtonsoft (.net library). This library provides methods that allows the programmer serialize and deserialize objects and more. There is a tutorial

(opens new window) if you want to know details about its methods and usages.

If you use Visual Studio, go to Tools/Nuget Package Manager/Manage Package to Solution/ and type "Newtonsoft" into the search bar and install the package. If you don’t have NuGet, this detailed tutorial

# C# Implementation

Before reading some code, it is important to undersand the main concepts that will help to program applications using json.

Serialization: Process of converting a object into a stream of bytes that can be sent through applications. The following code can be serialized and converted into the previous json.

Deserialization: Process of converting a json/stream of bytes into an object. Its exactly the opposite process of serialization. The previous json can be deserialized into an C# object as demonstrated in examples below.

To work this out, it is important to turn the json structure into classes in order to use processes already described. If you use Visual Studio, you can turn a json into a class automatically just by selecting "Edit/Paste Special/Paste JSON as Classes" and pasting the json structure.

# Serialization

The method ".SerializeObject" receives as parameter a type object, so you can put anything into it.

# Deserialization

You can receive a json from anywhere, a file or even a server so it is not included in the following code.

The method ".DeserializeObject" deserializes ‘jsonExample‘ into an "Author" object. This is why it is important to set the json variables in the classes definition, so the method access it in order to fill it.

# Serialization & De-Serialization Common Utilities function

This sample used to common function for all type object serialization and deserialization.

Работа с JSON

JSON (JavaScript Object Notation) является одним из наиболее популярных форматов для хранения и передачи данных. И платформа .NET предоставляет функционал для работы с JSON.

Основная функциональность по работе с JSON сосредоточена в пространстве имен System.Text.Json . Ключевым типом является класс JsonSerializer , который и позволяет сериализовать объект в json и, наоборот, десериализовать код json в объект C#.

Для сохранения объекта в json в классе JsonSerializer определен статический метод Serialize() и его асинхронный двойник SerializeAsyc() , которые имеют ряд перегруженных версий. Некоторые из них:

string Serialize(Object obj, Type type, JsonSerializerOptions options) : сериализует объект obj типа type и возвращает код json в виде строки. Последний необязательный параметр options позволяет задать дополнительные опции сериализации

string Serialize<T>(T obj, JsonSerializerOptions options) : типизированная версия сериализует объект obj типа T и возвращает код json в виде строки.

Task SerializeAsync(Stream utf8Json, Object obj, Type type, JsonSerializerOptions options) : сериализует объект obj типа type и записывает его в поток utf8Json. Последний необязательный параметр options позволяет задать дополнительные опции сериализации

Task SerializeAsync<T>(Stream utf8Json, T obj, JsonSerializerOptions options) : типизированная версия сериализует объект obj типа T в поток utf8Json.

Для десериализации кода json в объект C# применяется метод Deserialize() и его асинхронный двойник DeserializeAsync() , которые имеют различные версии. Некоторые из них:

object? Deserialize(string json, Type type, JsonSerializerOptions options) : десериализует строку json в объект типа type и возвращает десериализованный объект. Последний необязательный параметр options позволяет задать дополнительные опции десериализации

T? Deserialize<T>(string json, JsonSerializerOptions options) : десериализует строку json в объект типа T и возвращает его.

ValueTask<object?> DeserializeAsync(Stream utf8Json, Type type, JsonSerializerOptions options, CancellationToken token) : десериализует данные из потока utf8Json, который представляет объект JSON, в объект типа type. Последние два параметра необязательны: options позволяет задать дополнительные опции десериализации, а token устанавливает CancellationToken для отмены задачи. Возвращается десериализованный объект, обернутый в ValueTask

ValueTask<T?> DeserializeAsync<T>(Stream utf8Json, JsonSerializerOptions options, CancellationToken token) : десериализует данные из потока utf8Json, который представляет объект JSON, в объект типа T. Возвращается десериализованный объект, обернутый в ValueTask

Рассмотрим применение класса на простом примере. Сериализуем и десериализуем простейший объект:

Здесь вначале сериализуем с помощью метода JsonSerializer.Serialize() объект типа Person в стоку с кодом json. Затем обратно получаем из этой строки объект Person посредством метода JsonSerializer.Deserialize() .

Хотя в примере выше сериализовался/десериализовался объект класса, но подобным способом мы также можем сериализовать/десериализовать структуры.

Некоторые замечания по сериализации/десериализации

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

Сериализации подлежат только публичные свойства объекта (с модификатором public).

Запись и чтение файла json

Поскольку методы SerializeAsyc/DeserializeAsync могут принимать поток типа Stream, то соответственно мы можем использовать файловый поток для сохранения и последующего извлечения данных:

В данном случае вначале данные сохраняются в файл user.json и затем считываются из него.

Настройка сериализации с помощью JsonSerializerOptions

По умолчанию JsonSerializer сериализует объекты в минимифицированный код. С помощью дополнительного параметра типа JsonSerializerOptions можно настроить механизм сериализации/десериализации, используя свойства JsonSerializerOptions. Некоторые из его свойств:

AllowTrailingCommas : устанавливает, надо ли добавлять после последнего элемента в json запятую. Если равно true , запятая добавляется

DefaultIgnoreCondition : устанавливает, будут ли сериализоваться/десериализоваться в json свойства со значениями по умолчанию

IgnoreReadOnlyProperties : аналогично устанавливает, будут ли сериализоваться свойства, предназначенные только для чтения

WriteIndented : устанавливает, будут ли добавляться в json пробелы (условно говоря, для красоты). Если равно true устанавливаются дополнительные пробелы

Настройка сериализации с помощью атрибутов

По умолчанию сериализации подлежат все публичные свойства. Кроме того, в выходном объекте json все названия свойств соответствуют названиям свойств объекта C#. Однако с помощью атрибутов JsonIgnore и JsonPropertyName .

Атрибут JsonIgnore позволяет исключить из сериализации определенное свойство. А JsonPropertyName позволяет замещать оригинальное название свойства. Пример использования:

В данном случае свойство Age будет игнорироваться, а для свойства Name будет использоваться псевдоним «firstname». Консольный вывод:

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

Работа с JSON в C#: сериализация и десериализация объектов

Формат JSON, в настоящее время, один из наиболее часто используемых текстовых форматов данных, используемых как для хранения информации об объектах, так и для обмена этой информацией по Сети. В свою очередь, сериализация JSON — это очень важный момент при разработке различных веб-приложений. И сегодня мы рассмотрим один из вариантов сериализации/десериализации объектов C# с использованием классов и объектов, расположенных в пространстве имен System.Text.Json . Этот сериализатор с момента выхода .NET Core 3 претерпел значительные изменения и показывает достаточно хорошие результаты тестов.

Что такое «сериализация»?

В соответствии с определением, данным Microsoft, сериализация — это процесс преобразования объекта в поток байтов для сохранения или передачи в память, базу данных или файл. Сериализация используется для того, чтобы сохранить состояния объекта для последующего воссоздания при необходимости. Обратный процесс называется десериализацией.

Читать:
Как удалить вычисляемое поле в сводной таблице

Например, при разработке приложений в Visual Studio , активно используются файлы в формате JSON, позволяющие сохранять настройки вашего приложения и восстанавливать эти настройки при запуске. Например, в C# вы можете сохранить (сериализовать) положение и размер главного окна приложения и при повторном запуске приложения восстановить (десериализовать) эти настройки объекта (главного окна приложения).

Для сериализации/десериализации JSON в C# можно использовать как штатный сериализатор JsonSerializer , расположенный в пространстве имен System.Text.Json , так и решения сторонних разработчиков, например, часто используемый JSON.NET. Мы будем использовать штатный сериализатор.

Пример сериализации и десериализации JSON

Допустим, у нас имеется вот такой класс для хранения информации о человеке:

Создадим объект этого класса и сохраним состояние объекта в файл в формате JSON:

Здесь мы выполнили следующие действия:

  1. Создали сам объект для сериализации ( person )
  2. Сериализовали объект в строку ( string ) используя сериализатор JsonSerializer
  3. Записали полученную строку в текстовый файл person.json .

Теперь рядом с exe-файлом приложения появился файл со следующим содержимым:

Теперь мы можем при следующем запуске программы восстановить (десериализовать) этот объект в нашей программе, например, так:

Настройки сериализации JSON

Настройка сериализации с помощью JsonSerializerOptions

Для настройки сериализации мы можем передать в метод Serialize второй параметр — объект класса JsonSerializerOptions , который содержит настройки сериализации/десериализации объектов. Основные свойства этого класса следующие:

  • bool AllowTrailingCommas — устанавливает, надо ли добавлять после последнего элемента в json запятую. Если равно true , запятая добавляется
  • JsonNamingPolicy DictionaryKeyPolicy — возвращает или задает политику, используемую для преобразования имени ключа IDictionary в другой формат, например CamelCase.
  • JavaScriptEncoder Encoder — Возвращает или устанавливает кодировщик, используемый при экранировании строк. Укажите значение null для использования кодировщика по умолчанию
  • bool IgnoreNullValues — устанавливает, будут ли сериализоваться/десериализоваться в json объекты и их свойства со значением null
  • bool IgnoreReadOnlyProperties — аналогично устанавливает, будут ли сериализоваться свойства, предназначенные только для чтения
  • int MaxDepth — возвращает или задает максимальную глубину, разрешенную при сериализации или десериализации JSON, при этом значение по умолчанию 0 указывает максимальную глубину 64 .
  • bool PropertyNameCaseInsensitive — возвращает или задает значение, которое определяет, использует ли имя свойства сравнение без учета регистра во время десериализации. Значение по умолчанию — false .
  • JsonNamingPolicy PropertyNamingPolicy — возвращает или задает значение, указывающее политику, используемую для преобразования имени свойства объекта в другой формат, например CamelCase стиль, или null , чтобы оставить имена свойств без изменений.
  • JsonCommentHandling ReadCommentHandling — Возвращает или задает значение, определяющее, как комментарии обрабатываются во время десериализации
  • bool WriteIndented — устанавливает, будут ли добавляться в json пробелы (условно говоря, для красоты). Если равно true устанавливаются дополнительные пробелы

Рассмотрим несколько примеров использования этих настроек сериализации Json.

Как получить форматированную строку (с лидирующими пробелами) Json?

Для этого необходимо в настройках сериализации указать значение WriteIndented = true :

Как запретить экранировать строки при сериализации JSON?

В примере выше у нас все строки (имя, фамилия) экранированы. С точки зрения безопасности — это полностью правильное решение, но не всегда удобно для чтения. Чтобы позволить сериализатору не экранировать символы в строках мы можем воспользоваться свойством Encoder у JsonSerializerOptions следующим образом:

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

Как сериализовать имена свойств в CamelCase?

По умолчанию, сериализация имен свойств объекта проводится как есть, однако, если вам необходимо применить к именам свойств стиль CamelCase (он же «верблюжий»), то можно использовать следующую настройку сериализации:

Теперь наш объект в JSON будет выглядеть следующим образом:

Настройка сериализации с помощью атрибутов

При сериализации/десериализации объектов в JSON бывает необходимым исключить какое-либо свойство из строки JSON. Например, в нашем объекте Person таким свойством может быть свойство Age , так как мы можем легко рассчитать возраст человека, зная его день рождения и каждый раз «таскать» это свойство в JSON — смысла нет. В этом случае нам может пригодиться настройка сериализации JSON с использованием атрибутов. Для того, чтобы воспользоваться таким видом настройки, необходимо подключить пространство имен System.Text.Json.Serialization .

Исключим свойство Age из сериализуемых, используя атрибут JsonIgnore :

Также, часто используемым атрибутом для настройки сериализации/десериализации JSON является атрибут JsonPropertyName , который позволяет задать произвольное имя сериализуемому свойству. Например,

Теперь свойство Surname будет сериализоваться в JSON с именем PersonFamily .

Особенности сериализации и десериализации JSON

При сериализации/десериализации JSON с использованием штатного сериализатора JsonSerializer необходимо обратить внимание на следующие моменты:

Десериализуемый объект должен иметь конструктор без параметров

Например, во всех примерах по работе с JSON в C# мы использовали конструктор по умолчанию. Если бы наш класс имел, например, только вот такой конструктор:

То при попытке десериализовать такой объект мы получим исключение:

Сериализации подлежат только публичные свойства

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

Итого

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

Deserialize JSON with C#

I’m trying to deserialize a Facebook friend’s Graph API call into a list of objects. The JSON object looks like:

It’s not working, because the primitive object is invalid. How can I deserialize this?

10 Answers 10

You need to create a structure like this:

Then you should be able to do:

The names of my classes are just an example. You should use proper names.

Adding a sample test:

Peter Mortensen's user avatar

Icarus's user avatar

Sometimes I prefer dynamic objects:

Aman Agnihotri's user avatar

Bishoy Hanna's user avatar

A great way to automatically generate these classes for you is to copy your JSON output and throw it in here:

It will provide you with a starting point to touch up your classes for deserialization.

Very easily we can parse JSON content with the help of dictionary and JavaScriptSerializer. Here is the sample code by which I parse JSON content from an ashx file.

Peter Mortensen's user avatar

Newtonsoft.JSON is a good solution for these kind of situations. Also Newtonsof.JSON is faster than others, such as JavaScriptSerializer , DataContractJsonSerializer .

In this sample, you can the following:

Then you can cast jsonData to JArray , and you can use a for loop to get data at each iteration.

Also, I want to add something:

Working with dynamic object and using Newtonsoft serialize is a good choice.

Peter Mortensen's user avatar

I agree with Icarus (would have commented if I could), but instead of using a CustomObject class, I would use a Dictionary (in case Facebook adds something).

Peter Mortensen's user avatar

Stijn Bollen's user avatar

Serialization:

Deserialization::

To deserialize a dynamic object

Peter Mortensen's user avatar

If you’re using .NET Core 3.0, you can use System.Text.Json (which is now built-in) to deserialize JSON.

The first step is to create classes to model the JSON. There are many tools which can help with this, and some of the answers here list them.

Some options are http://json2csharp.com, http://app.quicktype.io, or use Visual Studio (menu EditPaste SpecialPaste JSON as classes).

Then you can deserialize using:

If you need to add settings, such as camelCase handling, then pass serializer settings into the deserializer like this:

Похожие статьи