Краткий экскурс
Фактически каждый программист рано (или поздно) сталкивается с сериализацией.
Сериализация — это процесс перевода структуры данных в последовательность битов, или же в другую структуру данных, которую удобно хранить, передавать.
Десериализация — это обратный процесс. Процесс преобразования сериализованных данных в структуру данных.
Подобные вещи часто встречаются при обмене данными между клиентом и сервером, между двумя клиентами (P2P). В общем много где встречается. Моё первое знакомство было при работе с API одного из российских сервисов.
API — это Application Programming Interface. То есть прослойка между функциональной частью какого-либо программного обеспечения и вашего программного обеспечения.
Например — Вам хочется написать программу, которая будет отображать погоду в Москве. Вам не хочется устанавливать свои метеодатчики и другое оборудование.
Допустим, что есть сервис «Погода в России», который имеет свой API. И данный сервис на бесплатно (или же платно) дает доступ к нему вашим приложениям. Конечно — всегда можно написать парсер нужной страницы и выводить информацию. Но любые изменения в содержимом страницы могут привести к тому, что парсер придется тоже обновлять.
Глупо говорить о преимуществах API по сравнению с парсингом. Это скорость, удобство работы, а также, очень часто, более расширенный функционал.
Так что если сервис предлагает API — глупо отказываться.
Сериализация
В данном примере мы рассмотрим библиотеку «Newtonsoft.Json» для работы с JSON. Почему её? Потому что она удобная.
Для начала её нужно добавить в references.
Для этого нужно нажать ПКМ на References и выбрать «Добавить ссылку…».
Тут можно найти его в поиске (если уже использовали), скачать его через NuGet, или же просто добавить как обычную библиотеку через «Обзор».
На всякий случай оставлю библиотеку тут: скачать Newtonsoft.Json.dll.
Теперь можно приступить к коду.
Для начала нужно добавить NameSpace библиотеки в код. Для этого добавим в using следующую строку:
1 2 3 |
using System; // Далее ваши библиотеки using Newtonsoft.Json; |
Теперь нужно описать класс, который будем сериализовать и десериализовать:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
class MyMusic { public Track[] Tracks { get; set; } } class Track { public string Artist { get; set; } public string Album { get; set; } public string Title { get; set; } public string Year { get; set; } } |
Будем считать, что пишем программу для ведения учета домашней музыкальной коллекции. Базовый класс — MyMusic, вспомогательный класс — Track.
Теперь добавим несколько треков:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
MyMusic myCollection = new MyMusic(); myCollection.Tracks = new Track[3]; myCollection.Tracks[0] = new Track() { Artist="Artist1", Album="Album1", Title="Title1", Year="2015" }; myCollection.Tracks[1] = new Track() { Artist = "Artist2", Album = "Album2", Title = "Title2", Year = "2015" }; myCollection.Tracks[2] = new Track() { Artist = "Artist3", Album = "Album3", Title = "Title3", Year = "2015" }; |
Теперь сериализуем этот класс и выведем на RichTextBox:
1 2 |
string serialized = JsonConvert.SerializeObject(myCollection); richTextBox.Text = serialized; |
В результате чего мы должны получить такую строку на выходе:
1 |
{"Tracks":[{"Artist":"Artist1","Album":"Album1","Title":"Title1","Year":"2015"},{"Artist":"Artist2","Album":"Album2","Title":"Title2","Year":"2015"},{"Artist":"Artist3","Album":"Album3","Title":"Title3","Year":"2015"}]} |
Десериализация
Теперь нужно эту строку десериализовать обратно в класс. Для этого, естественно, должен быть объявлен соответствующий класс, иначе программа не сможет ничего десериализовать.
Сам код десериализации следующий:
1 2 |
string json = richTextBox.Text; MyMusic newMusic = JsonConvert.DeserializeObject<MyMusic>(json); |
Теперь выведем на экран содержимое десериализованного JSON’а:
1 2 3 4 5 |
richTextBox.Text = "Всего треков добавлено: "+newMusic.Tracks.Length+Environment.NewLine; foreach(var track in newMusic.Tracks) { richTextBox.Text += track.Artist + " (" + track.Album + "-" + track.Year + ") - " + track.Title + Environment.NewLine; } |
На экран должно вывестись следующий текст:
1 2 3 4 |
Всего треков добавлено: 3 Artist1 (Album1-2015) - Title1 Artist2 (Album2-2015) - Title2 Artist3 (Album3-2015) - Title3 |
Как видите — с JSON очень удобно работать. Но есть одна маленькая хитрость, которая сильно упростит вашу жизнь при десериализации. Чтобы вам вручную не создавать огромные классы анализируя пример JSON’а, который вам возвращает API — можно его сгенерировать автоматически. В этом вам поможет сайт Json2CSharp. Просто вставьте в него строку с JSON, которую вы получили из API и он сгенерирует вам необходимые классы. Основной класс будет всегда RootObject (в примере был MyMusic), но никто не мешает вам его переименовать в нужный.
Скачать весь проект в 7Z-архиве.
Пароль к архиву: котодомик.рф
Update 08.07.2019
Важный момент.
Класс, который Вы хотите сериализовать/десериализовать, должен соответствовать некоторым требованиям, чтобы не было проблем при работе с ним:
- У класса должен быть обязательно объявлен конструктор без параметров, или не объявлено конструкторов вовсе;
- Лучше использовать свойства, а не поля (с {get; и set;} как в примерах выше;
- Если у свойства отсутствует get’тер, или set’тер — то будьте готовы к тому, что часть функционала JSON-сериализатора будет работать не верно. Например:
- У вас отсутствует публичный GET’тер, но есть SET’тер. Тогда вы сможете десериализовать (JSON в объект) свойство объекта, но сериализовать (объект в JSON) его вы не сможете;
- У вас отсутствует публичный SET’тер, но есть GET’тер. Тогда вы не сможете десериализовать (JSON в объект) свойство объекта, но сможете его сериализовать (объект в JSON);