Daj się poznać 2017

JSON.NET: serializacja i przeszukiwanie danych

Ostatnio opisywałem sposób zapisu danych, który możemy realizować w .NET ale i nie tylko. Moja aplikacja Codziennik, musi przechowywać dane. Z racji tego, zacząłem testować różne sposoby przechowywania danych. Dzisiaj chciałem zaprezentować sposób obsługi danych zapisanych w formacie JSON za pomocą platformy .NET. Ja korzystam do tego z biblioteki nazywającej się Json.NET od Newtonsoft.

Instalacja pakietu

Aby z niej korzystać wystarczy do naszego projektu doinstalować odpowiedni NuGet. Możemy to zrobić za pomocą managera NuGetów, wpisując w wyszukiwarkę np.: json.net lub poprzez konsolę wpisując polecenie PM> Install-Package Newtonsoft.Json.

Jeszcze na wstępie chciałbym wyjaśnić parę kwestii, głównie związanych z nazewnictwem. Zapisywanie danych do postaci JSONa nazywamy serializacją. Deserializacja natomiast to proces odwrotny, czyli „tłumaczenie” danych zapisanych w JSONie na obiekt(y). Bardzo fajnie obrazuje to ta grafika:

W początkowych przykładach będziemy operować na takiej oto klasie reprezentującej nasze dane:

  
public class Entry  
{ 
   public DateTime Date;  
   public string Content;  
}  

Wszystkie kwestie na ten moment zostały wyjaśnione więc możemy lecieć z konkretnymi przykładami.

Proste przykłady użycia

Na początek bardzo proste przykłady korzystające z powyższej klasy:

  • Serializacja pojedynczego obiektu:
	//Tworzymy obiekt do badań
	Entry entry =new Entry();
	entry.Date = new DateTime(2017, 03, 18);
	entry.Content = "Testowy wpis";
	
	//Teraz czas na serializację
	string json = JsonConvert.SerializeObject(entry);
	Console.WriteLine(json);
	

Dzięki temu na konsole wypisany zostanie taki oto string:

{
	"Date": "2017-3-18T00:00:00Z"
	"Content": "Testowy wpis"
}
  • Deserializacja pojedynczego obiektu

Teraz zdeserializuję powyższy JSON

string json = 
@"{
	"Date": "2017-3-18T00:00:00Z"
	"Content": "Testowy wpis"
}";

Entry entry = JsonConvert.DeserializeObject<Entry>(json);

Wynikiem tej operacji będzie instancja obiektu Entry o następujących polach:

entry.Date == "18.03.2017 00:00"
entry.Content == "Testowy wpis"

Jak widać, do serializacji i deseralizacji używamy klasy JsonConvert. Metodą odpowiedzialną za serializację jest .SerializeObject(), która jako parametr przyjmuje obiekt, który ma zostać zserializowany.

Do deserializacji służy metoda .DeserializeObject<>() przyjmująca typ na jaki ma „przekodować” naszego JSONa oraz jako parametr stringa z którego ma wyciągnąć informacje o danym obiekcie.

Bardziej zaawansowane przykłady

Teraz przejdziemy do bardziej zaawansowanych przykładów. Zazwyczaj chcemy przetrzymywać dane dotyczące nie jednego, ale kilkuset, czy kilku tysięcy wpisów. Przecież nie będziemy każdego z osobna serializować i dopisywać do stringa. Klasa JsonConvert w metodzie .SerializeObject() jako argument przyjmuje obiekt. Więc równie dobrze zamiast naszego entry możemy podać tam listę obiektów. Popatrzmy na poniższy przykład:

List<Entry> wpisy = new List<Entry>();

//Za pomocą for-a dodaję do listy 30 wpisów, o datach od 1 do 30 marca 2017
//i treści "i-ty wpis", gdzie i jest zmienną z przedziału od 1 do 30
//(1 dla pierwszego wpisu, 30 dla ostatniego)

for (int i = 1; i <= 30; i++)
{
          wpisy.Add(new Entry()
          {
              Date = new DateTime(2017, 03, i),
              Content = $"{i}-ty wpis"
           });
}

string serialized = JsonConvert.SerializeObject(wpisy);

Nasz string zawiera teraz dane w formacie JSON dotyczące 30 wpisów. Wygląda on następująco:

[{
	"Date": "2017-03-01T00:00:00",
	"Content": "1-ty wpis"
},
.
.
.
{
	"Date": "2017-03-02T00:00:00",
	"Content": "30-ty wpis"
}]

Deserializacja JSONa do listy też jest bardzo łatwa. Tak jak w prostym przykładzie deserializacji jako obiekt w ostrych nawiasach podawaliśmy Entry teraz podamy List<Entry>. Użyjemy stringa serialized z JSONem z poprzedniego przykładu. Będzie to wyglądało następująco:

List<Entry> entriesList = JsonConvert.DeserializeObject<List<Entry>>(serialized);

Utworzona w ten sposób lista entriesList zawiera 30 obiektów typu Entry.

Json.NET + LINQ = <3

Jedną z fajniejszych rzeczy w Json.NET jest to, że można razem z nim używać LINQ1.

Ostatnią rzeczą, o której chciałem dzisiaj napisać jest właśnie używanie LINQ przy danych z JSONa. Najpierw przedstawię kod, a później go objaśnię:

JArray entriesArray = JArray.Parse(serialized);

var postDates = (from s in entriesArray 
                 select s["Date"]).ToList();

foreach (var date in postDates)
{
       Console.WriteLine(date);
}

Żeby używać LINQ musimy najpierw parsować dane z formatu JSON na obiekt typu JArray. Jest on po prostu tablicą znaczników które zapisane są w JSONie.

Następnie używam właśnie LINQ. Tworzę obiekt(w tym przypadku listę) do którego zapisuje wszystko, co wyciągnęło nam zapytanie. A samo zapytanie wybiera nam obiekty s z entriesArray i wybiera nam wartości nazwane Date. Metoda .ToList() tworzy z wybranych elementów listę. Następnie mamy pętlę foreach, której efektem będzie wypisanie dat wszystkich wpisów do konsoli:

01.03.2017 00:00:00
02.03.2017 00:00:00
.
.
.
30.03.2017 00:00:00

Możliwość używania LINQ to jedna z lepszych rzeczy jakie oferuje nam Json.NET. Dokładnie nie wgłębiłem się jeszcze w możliwości tego języka. Na pewno zrobię to przy okazji odpytywania magazynu danych w aplikacji Codziennik o której więcej mam nadzieję, już niedługo.

Json.NET jest najpopularniejszym rozwiązaniem do obsługi formatu JSON na platformę Microsoftu. Dodatkowo testy wykazały, że jest to też biblioteka najszybciej wykonująca operacje na JSONie.

Do innych zalet biblioteki json.NET zaliczyć należy formatowanie daty i czasu zapisanych w typie DateTime. Zostało to bardzo dobrze przedstawione w oficjalnej dokumentacji dotyczącej serializacji dat w Json.NET.

Jak widać obsługa biblioteki Json.NET nie wymaga tak naprawdę długiego studiowania dokumentacji. Wystarczy zobaczyć przykłady, a następnie korzystać z podpowiedzi IntelliSense. Jest to narzędzie bardzo intuicyjne. Mi korzysta się z niego bardzo przyjemnie. Jeśli potrzeba wykonywać jakieś bardzo skomplikowane operacje z pomocą przychodzi oficjalna dokumentacja. Jest bardzo dobrze napisana. Przykłady dodatkowo rozjaśniają użycie.

Grafika z jajkiem i ptakiem pochodzi stąd


  1. Za Wikipedią: LINQ umożliwia zadawanie pytań na obiektach. Składnia języka LINQ jest prosta i przypomina SQL

Zostaw odpowiedź

Twój adres email nie zostanie upubliczniony.* Pola wymagane *