Grafikus C# – Windows Forms tanfolyam › 10.6 lecke

Windows Forms · 10.6 lecke · JSON

JSON szerializálás és visszaolvasás

A CSV (10.5 lecke) lapos táblázatot ír le. A programok adatai viszont gyakran összetettebbek: egy névjegyhez több telefonszám, egy jegyzethez címkék, egy beállításhoz beágyazott csoportok tartoznak. Erre való a JSON (JavaScript Object Notation), a mai programozás egyik legelterjedtebb adatformátuma: ember által is olvasható, szöveges, és minden nyelv kezeli. A szerializálás az objektum → JSON szöveg alakítás, a deszerializálás a visszaalakítás. Ebben a leckében a beépített System.Text.Json osztályt használod: objektumot mentesz és töltesz be, megoldod az ékezetek, az enum és a dátum kérdését, a verziózást, és kezeled a hibás fájlokat.

  • kb. 110 perc
  • haladó szint
  • JSON
Diáklány C# programot készít laptopon

A lecke végére

  • olvasod a JSON szerkezetét (objektum, tömb, szöveg, szám, logikai, null);
  • objektumot szerializálsz és deszerializálsz (JsonSerializer.Serialize, Deserialize<T>);
  • beállítod a JsonSerializerOptions értékeit (WriteIndented, ékezetes betűk, enum szövegként, camelCase);
  • tudod, hogy a tulajdonságokat menti, a mezőket nem, és használod a [JsonIgnore], [JsonPropertyName] attribútumokat;
  • verziót (Verzio) tárolsz, és kezeled a hiányzó vagy új mezőket;
  • a hibás JSON-t (JsonException) érthetően jelzed, és a fájlkezelést biztonságossá teszed.

Mielőtt elkezded

Ehhez a leckéhez a 10.1–10.3 lecke (fájlkezelés, kódolás), a 3.9 lecke (osztályok, tulajdonságok) és a 8.4 lecke (List<T>) szükséges. A System.Text.Json a .NET Core 3.0 / .NET 5 és újabb projektekben beépített; a régi .NET Framework projektben külön NuGet-csomagként adható hozzá (vagy a harmadik fél Newtonsoft.Json könyvtára használható).

10.5 CSV →

A JSON felépítése

nevjegyek.jsonJSON
{
"verzio": 1,
"nevjegyek": [
{
"nev": "Kiss Anna",
"telefonok": ["+36 30 123 4567", "+36 20 765 4321"],
"szuletes": "2009-03-14T00:00:00",
"baratom": true,
"megjegyzes": null
}
]
}
ObjektumKapcsos zárójel { }: név: érték párok. A nevek mindig idézőjelben, szövegként állnak. Az objektum a C# osztály megfelelője.
TömbSzögletes zárójel [ ]: értékek sorozata. A C# List<T> vagy tömb megfelelője.
Érték típusokSzöveg ("..."), szám, logikai (true/false), null, objektum, tömb. A dátumnak nincs saját típusa: szövegként (ISO 8601) tárolódik.
Szigorú szabályokNincs megjegyzés, nincs záró vessző az utolsó elem után, a szöveg idézőjele mindig kettős ("). A kézzel szerkesztett fájl ezeken a szabályokon szokott elhasalni.

Jósolj!

Egy kézzel szerkesztett JSON-ban az utolsó tömbelem után vessző maradt: [1, 2, 3,]. Elfogadja-e ezt a System.Text.Json alapbeállítással?

Jóslat ellenőrzése

Nem: JsonException kivételt dob (a JSON szabvány nem engedi a záró vesszőt). A JsonSerializerOptions.AllowTrailingCommas = true engedékenyebbé teszi, de saját programnál a hibás fájlt érdemes jelezni.

Szerializálás és visszaolvasás

Form1.cs (using System.Text.Json; using System.IO;)C#
public class Nevjegy
{
public string Nev { get; set; } = "";
public List<string> Telefonok { get; set; } = new List<string>();
public DateTime Szuletes { get; set; }
public bool Baratom { get; set; }
public string Megjegyzes { get; set; } // lehet null
}

private static readonly JsonSerializerOptions beallitas = new JsonSerializerOptions
{
WriteIndented = true, // tagolt, olvasható kimenet
PropertyNamingPolicy = JsonNamingPolicy.CamelCase, // Nev → nev, Telefonok → telefonok
Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping // az ékezetes betűk ne \u00F5 alakban íródjanak
};

// objektum → JSON szöveg
string json = JsonSerializer.Serialize(nevjegyek, beallitas);
File.WriteAllText(ut, json, new UTF8Encoding(false)); // a JSON szabvány UTF-8, BOM nélkül

// JSON szöveg → objektum
string beolvasott = File.ReadAllText(ut, Encoding.UTF8);
List<Nevjegy> vissza = JsonSerializer.Deserialize<List<Nevjegy>>(beolvasott, beallitas) ?? new List<Nevjegy>();
Serialize és Deserialize<T>A Serialize az objektum nyilvános tulajdonságaiból szöveget készít. A Deserialize<T> a szövegből T típusú objektumot épít: a T-nek paraméter nélküli konstruktora és írható tulajdonságai kellenek. Üres vagy null JSON-ra null az eredmény: ezért a ?? new List<...>().
ÉkezetekAz alapértelmezett kódoló az ASCII-n kívüli betűket \u00F5 alakban írja (a fájl így is helyes, de olvashatatlan). Az UnsafeRelaxedJsonEscaping az ékezetes betűket változatlanul hagyja. A név unsafe (nem biztonságos) HTML-be ágyazott JSON-nál számít; fájlba írásnál elfogadható.
CamelCaseA JSON-ban a szokás a kisbetűvel kezdődő név (nev). A PropertyNamingPolicy ezt automatikusan intézi: a C# név marad Nev. Visszaolvasásnál ugyanazt a beállítást kell használni (vagy PropertyNameCaseInsensitive = true).
UTF-8, BOM nélkülA JSON szabvány szerint UTF-8 kódolású, BOM nélkül (10.3 lecke). A File.WriteAllText alapértelmezése is ez; a ReadAllText felismeri a BOM-ot, ha van.

Jósolj!

A Nevjegy osztályban a public string Nev; mező (nem tulajdonság: nincs { get; set; }). Mi kerül a JSON-ba ebből a mezőből?

Jóslat ellenőrzése

Semmi: a System.Text.Json alapból csak a nyilvános tulajdonságokat szerializálja, a mezőket nem (az IncludeFields = true beállítás vagy a [JsonInclude] bekapcsolja). A csendben kimaradó adat gyakori hibaforrás: használj tulajdonságot.

Típusok, attribútumok és beállítások

Nevjegy.cs (using System.Text.Json.Serialization;)C#
public enum Kategoria { Csalad, Iskola, Munka }

public class Nevjegy
{
public string Nev { get; set; } = "";

[JsonConverter(typeof(JsonStringEnumConverter))] // az enum szövegként: "Iskola" a 1 helyett
public Kategoria Kategoria { get; set; }

[JsonPropertyName("szuletesiDatum")] // a JSON-beli név megadása
public DateTime Szuletes { get; set; }

[JsonIgnore] // ez nem kerül a fájlba (számított érték)
public int Kor { get { return DateTime.Today.Year - Szuletes.Year; } }

[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] // a null értéket nem írja ki
public string Megjegyzes { get; set; }
}

// beállítások: az enum szövegként és a hibatűrőbb olvasás
var beallitas = new JsonSerializerOptions
{
WriteIndented = true,
PropertyNameCaseInsensitive = true, // olvasáskor a kis- és nagybetű nem számít
Converters = { new JsonStringEnumConverter() }, // minden enum szövegként
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
};
C# típusJSONMegjegyzés
stringszövegÉkezetek: UnsafeRelaxedJsonEscaping.
int, double, decimalszámMindig tizedespont, a kultúrától függetlenül (a JSON szabvány szerint).
booltrue / false
DateTimeszöveg (ISO 8601)"2026-10-28T10:30:00"; az időzóna jelzése (Kind) fontos lehet.
enumszám (alap) vagy szövegA szöveg biztonságosabb: az enum sorrendje változhat.
List<T>, tömbtömb
Dictionary<string, T>objektumA kulcs szöveg.
Color, Font, Image—Nem szerializálhatók jól: tárolj szöveget (#RRGGBB, 7.9 lecke), betűnevet és méretet.

Jósolj!

A Kategoria enum Csalad, Iskola, Munka sorrendben van, és a fájlba számként (1 = Iskola) mentesz. Később beszúrsz egy új értéket az enum elejére (Egyeb). Mi történik a régi fájlokkal?

Jóslat ellenőrzése

Az új sorrendben az 1 már Csalad: a régi fájl minden adata csendben rossz kategóriába kerül. Szövegként tárolva ("Iskola") az új érték beszúrása nem rontja el a régi adatot.

Verzió, hiányzó mezők és hibás JSON

A fájl a program régebbi változatától is származhat, és a felhasználó kézzel is javíthatja. Ezért (1) a fájl egy burkoló objektumban tárolja az adatot és a verzio számot, (2) az új mezők alapértéket kapnak, ha a régi fájlban hiányoznak, (3) a betöltés hibatűrő:

Form1.csC#
public class Adatfajl
{
public int Verzio { get; set; } = 2;
public List<Nevjegy> Nevjegyek { get; set; } = new List<Nevjegy>();
}

private Adatfajl Betolt(string ut, out string hiba)
{
hiba = "";

try
{
string json = File.ReadAllText(ut);

Adatfajl adat = JsonSerializer.Deserialize<Adatfajl>(json, beallitas);

if (adat == null) { hiba = "A fájl üres."; return null; }

if (adat.Verzio > 2) { hiba = "A fájlt a program újabb változata írta (" + adat.Verzio + "). Frissítsd a programot."; return null; }

if (adat.Verzio < 2) { Atalakit1rol2ra(adat); } // régi formátum áttérése

return adat;
}
catch (JsonException ex)
{
hiba = "A fájl hibás JSON (sor: " + (ex.LineNumber + 1) + ", pozíció: " + ex.BytePositionInLine + "): " + ex.Message;
}
catch (FileNotFoundException) { hiba = "A fájl nem található."; }
catch (IOException ex) { hiba = "A fájl nem olvasható: " + ex.Message; }
catch (UnauthorizedAccessException) { hiba = "Nincs jogosultság a fájlhoz."; }

return null; // a hívó a hibával tájékoztatja a felhasználót; a meglévő adat érintetlen marad
}
Burkoló objektum + verzióA fájl legfelső szintje objektum (nem tömb): így később új adat kerülhet mellé (beállítások, metaadat) anélkül, hogy a régi fájl érvénytelen lenne. A Verzio mondja meg, milyen alakú az adat.
AlapértékekHa egy mező hiányzik a fájlból, az objektum a konstruktor/inicializáló alapértékét kapja (= new List<...>(), = ""). Új tulajdonságnak adj értelmes alapértéket: a régi fájl így is betölthető.
Ismeretlen mezőkA System.Text.Json a ismeretlen mezőket alapból figyelmen kívül hagyja (újabb fájl régebbi programmal: az új mezők elvesznek, mentéskor nem kerülnek vissza). A Verzio ellenőrzése ezt jelezheti.
JsonExceptionA hibás JSON JsonException kivételt dob, amely tartalmazza a sor- és pozíciószámot: ezt érdemes mutatni a felhasználónak. A hibás fájl ne írja felül az épet.

Jósolj!

A program betölti a hibás JSON-t, a Deserialize kivételt dob, de a kód a catch blokkban üres listát állít be, majd a következő mentéskor ezt írja a fájlba. Mi történik a felhasználó adataival?

Jóslat ellenőrzése

Az adatok véglegesen elvesznek: a hibás (de talán javítható) fájlt az üres lista felülírja. Helyes: a betöltés hibájánál a program jelezzen, a meglévő fájlt ne módosítsa, és legfeljebb biztonsági másolatot (.bak) készítsen róla (10.9 lecke).

📷 Képernyőkép helye

Mit tegyél ide: a névjegyzék, mellette a JSON fájl tartalma egy szövegszerkesztőben (tagolt, ékezetes betűkkel).Javasolt fájlnév: winforms-10-6-nevjegyzek.webp · Alt szöveg: Névjegyzék és a JSON fájl

Hibakeresés: te vagy a hibadetektív

Mi a baj, és hogyan javítod?

Gondold végig az okot, és csak utána nyisd le a megoldást.

1. Üres JSON: {}

public class Diak { public string Nev; public int Pont; }   // mezők
Hiba és javítás

Mezőket a System.Text.Json alapból nem szerializál. Írd tulajdonsággá ({ get; set; }), vagy kapcsold be az IncludeFields beállítást.

2. Az olvasás után minden tulajdonság üres

A fájl nev, az osztály Nev: a betöltött érték üres.

Ok és javítás

A kis- és nagybetű eltérése. Használd ugyanazt a PropertyNamingPolicy értéket olvasáskor és íráskor, vagy állítsd be a PropertyNameCaseInsensitive = true értéket.

3. A fájlban \u00E1 jelek vannak az ékezetek helyén

A JSON helyes, de szerkesztőben olvashatatlan.

Ok és javítás

Az alapértelmezett kódoló az ASCII-n kívüli betűket escape-eli. Állítsd be: Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping.

4. JsonException a betöltéskor

List<Nevjegy> lista = JsonSerializer.Deserialize<List<Nevjegy>>(File.ReadAllText(ut));   // a fájl burkoló objektum, nem tömb
Hiba és javítás

A típus nem egyezik a fájl szerkezetével (a legfelső szint objektum, nem tömb). Deszerializálj az Adatfajl típusba, és try–catch-eld.

5. A régi fájl betöltése után az új mező értéke nulla

Az új Prioritas mező nulla vagy üres a régi fájlból.

Ok és javítás

A hiányzó mező az alapértéket kapja. Adj értelmes alapértéket az inicializálóban, vagy végezz verzió-átalakítást betöltés után.

6. Kör-hivatkozás: JsonException a mentéskor

class Csoport { public List<Tag> Tagok { get; set; } }
class Tag { public Csoport Csoport { get; set; } } // a Tag visszamutat a Csoportra
Hiba és javítás

Körkörös hivatkozást a szerializáló nem tud kiírni (végtelen mélység). Törd meg a kört: a visszamutató tulajdonságot jelöld [JsonIgnore] attribútummal, és betöltés után állítsd vissza.

Mini projekt: névjegyzék JSON-ben

Készíts névjegyzék-kezelőt, amelynek adatai JSON-fájlban tárolódnak:

  1. Modell: a Nevjegy osztály (Id mint Guid, Nev, Telefonok lista, Email, Szuletes mint DateTime?, Kategoria enum, Megjegyzes), és az Adatfajl burkoló (Verzio, Nevjegyek).
  2. Felület: bal oldalon lstNevek (rendezett), fölötte txtKereses; jobb oldalon a szerkesztő mezők: txtNev, txtEmail, dtpSzuletes (+ chkSzuletes: van-e adat), cmbKategoria, lstTelefonok (+ és − gombbal), txtMegjegyzes; gombok: Új, Mentés, Törlés, Exportálás..., Importálás....
  3. Tárolás: nevjegyek.json az adatmappában (10.1 lecke); indításkor a betöltés, módosításkor a mentés (a Mentés gomb, kilépéskor kérdés); beállítások: tagolt, ékezetes, enum szövegként, null kihagyva.
  4. Hibatűrés: hibás JSON esetén a program jelzi a sort és a pozíciót, nem írja felül a fájlt, felajánlja a fájl átnevezését (.hibas) és az üres listával indulást (a felhasználó kéri); a hiányzó fájl az első indításnál nem hiba.
  5. Ellenőrzés: a név kötelező (legfeljebb 60 karakter); az e-mail egyszerű mintája (@ és pont a @ után); a telefonszám csak szám, szóköz, +, -, zárójel; ismétlődő név esetén figyelmeztetés; a mentés előtt az Id egyedi.
  6. Keresés és rendezés: a lista név szerint (ékezetfüggetlen kereséssel, 10.3 lecke Ekezetmentes); kategória szerinti szűrő.
  7. Verzió: a fájl Verzio = 2; a program az 1-es fájlt (ahol a Telefon egyetlen szöveg volt) betölti, és áttéri a Telefonok listára; újabb fájlra figyelmeztet.
  8. Export és import: exportálás (CSV: 10.5 lecke, JSON: egy kijelölt névjegy, vagy az összes); import: JSON-ból az Id szerinti egyesítés (az azonos Id felülírás előtt kérdés).
  9. Teszteld: ékezetes nevek és megjegyzések, üres és hibás fájl (szándékosan elrontott vessző), régi (1-es verziójú) fájl, null mezők, dátum nélküli névjegy, nagy lista (1000 névjegy), a fájl kézi szerkesztése után újraindítás, kategória átírása szövegként.
Megoldás megnyitása (próbáld ki előbb önállóan!)

A modell és a betöltés a leckében látható; itt a tárolás és az áttérés (verzió) logikája áll.

Tarolo.cs (using System.Text.Json; using System.Text.Json.Serialization; using System.IO; using System.Text; using System.Linq; using System.Collections.Generic;)C#
public enum Kategoria { Egyeb, Csalad, Iskola, Munka }

public class Nevjegy
{
public Guid Id { get; set; } = Guid.NewGuid();
public string Nev { get; set; } = "";
public List<string> Telefonok { get; set; } = new List<string>();
public string Email { get; set; }
public DateTime? Szuletes { get; set; }
public Kategoria Kategoria { get; set; } = Kategoria.Egyeb;
public string Megjegyzes { get; set; }

// a régi (1-es verziójú) fájl egyetlen Telefon szövege: csak olvasásra, mentéskor nem íródik ki
public string Telefon { get; set; }
}

public class Adatfajl
{
public int Verzio { get; set; } = 2;
public List<Nevjegy> Nevjegyek { get; set; } = new List<Nevjegy>();
}

public static class Tarolo
{
public const int AktualisVerzio = 2;

public static readonly JsonSerializerOptions Beallitas = new JsonSerializerOptions
{
WriteIndented = true,
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
PropertyNameCaseInsensitive = true,
Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
Converters = { new JsonStringEnumConverter() },
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull // a null (például a régi Telefon) nem íródik ki
};

public static string Ut()
{
string mappa = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Nevjegyzek");

Directory.CreateDirectory(mappa);

return Path.Combine(mappa, "nevjegyek.json");
}

// eredmény: az adat, vagy null és a hiba szövege; a hiányzó fájl nem hiba (üres adat)
public static Adatfajl Betolt(string ut, out string hiba)
{
hiba = "";

if (!File.Exists(ut)) { return new Adatfajl(); }

try
{
Adatfajl adat = JsonSerializer.Deserialize<Adatfajl>(File.ReadAllText(ut, Encoding.UTF8), Beallitas);

if (adat == null) { hiba = "A fájl üres."; return null; }
if (adat.Verzio > AktualisVerzio) { hiba = "A fájlt a program újabb változata írta (verzió: " + adat.Verzio + ")."; return null; }

if (adat.Verzio < 2)
{
foreach (Nevjegy n in adat.Nevjegyek)
{
if (!string.IsNullOrWhiteSpace(n.Telefon)) { n.Telefonok.Add(n.Telefon); } // áttérés: egy szövegből lista

n.Telefon = null;
}

adat.Verzio = 2;
}

// az azonosítók egyedisége: a hiányzó vagy ismétlődő Id újat kap
HashSet<Guid> latott = new HashSet<Guid>();

foreach (Nevjegy n in adat.Nevjegyek) { if (n.Id == Guid.Empty || !latott.Add(n.Id)) { n.Id = Guid.NewGuid(); latott.Add(n.Id); } }

return adat;
}
catch (JsonException ex) { hiba = "Hibás JSON (sor: " + ((ex.LineNumber ?? 0) + 1) + ", pozíció: " + (ex.BytePositionInLine ?? 0) + "): " + ex.Message; }
catch (IOException ex) { hiba = "A fájl nem olvasható: " + ex.Message; }
catch (UnauthorizedAccessException) { hiba = "Nincs jogosultság a fájlhoz."; }

return null;
}

public static bool Ment(string ut, Adatfajl adat, out string hiba)
{
hiba = "";

try
{
adat.Verzio = AktualisVerzio;

string ideiglenes = ut + ".tmp";

File.WriteAllText(ideiglenes, JsonSerializer.Serialize(adat, Beallitas), new UTF8Encoding(false));

if (File.Exists(ut)) { File.Replace(ideiglenes, ut, ut + ".bak"); } // a régi fájl biztonsági másolata
else { File.Move(ideiglenes, ut); }

return true;
}
catch (IOException ex) { hiba = "A mentés nem sikerült: " + ex.Message; }
catch (UnauthorizedAccessException) { hiba = "Nincs jogosultság a mentéshez."; }

return false;
}
}
📷 Képernyőkép helye

Mit tegyél ide: a kész névjegyzék-kezelő a szerkesztő mezőkkel és a kategória-szűrővel.Javasolt fájlnév: winforms-10-6-kesz.webp · Alt szöveg: A kész névjegyzék-kezelő

Három önálló gyakorlófeladat

Egyszerre csak egyet csinálj: tervezd meg, írd meg, futtasd, ellenőrizd, és csak utána nyisd ki a megoldást.

1. Színek mentése

A program témájának három színét (Color) JSON-ban mented. Hogyan?

Egy lehetséges megoldás

A Color közvetlenül nem szerializálható jól. Tárold HTML-színként (#RRGGBB): a ColorTranslator.ToHtml és FromHtml metódusokkal (7.9 lecke).

Tema.csC#
public class Tema{    public string HatterSzin { get; set; } = "#FFFFFF";    public string SzovegSzin { get; set; } = "#000000";    [JsonIgnore] public Color Hatter { get { return ColorTranslator.FromHtml(HatterSzin); } set { HatterSzin = ColorTranslator.ToHtml(value); } }}

2. Szótár mentése

Egy Dictionary<string, int> szójárást (szó → előfordulás) mentesz. Milyen lesz a JSON?

Egy lehetséges megoldás

Objektum: { "alma": 5, "körte": 2 }; a kulcs szöveg. Nem szöveges kulcsnál (például int) a .NET újabb verziói elfogadják, régebbiek nem: szöveg kulcsot használj.

3. Betöltés ismeretlen szerkezetből

Egy JSON-ból csak egy mezőt ("cim") kell kiolvasnod, a teljes szerkezetet nem ismered. Mit használsz?

Egy lehetséges megoldás

A JsonDocument.Parse (csak olvasható dokumentum-fa): doc.RootElement.GetProperty("cim").GetString(); a TryGetProperty kivétel nélkül jelzi a hiányzó mezőt. A JsonDocument IDisposable: using.

Form1.csC#
using (JsonDocument doc = JsonDocument.Parse(json)){    JsonElement cim;    if (doc.RootElement.TryGetProperty("cim", out cim)) { lblCim.Text = cim.GetString(); }}

Gyakorlótár: 6 további feladat

Három szinten gyakorolhatsz: alap, közepes és kihívás. Csak a próbálkozás után nyisd le a megoldást.

Alap szint

1. JSON olvasása

Olvasd le a JSON-ból: mi a nev értéke és hány telefonszám van? {"nev":"Anna","telefonok":["1","2"]}

Megoldás megnyitása

A nev értéke Anna, a telefonok tömbjében 2 elem van.

2. Mi hiányzik?

A public int Pont; mezőt a szerializáló kihagyta. Miért?

Megoldás megnyitása

Mező, nem tulajdonság: public int Pont { get; set; } vagy IncludeFields kell.

Közepes szint

3. Dátum formátuma

A dátum a JSON-ban "2026-10-28T00:00:00". Hogyan kapod meg a DateTime értéket, és hogyan jelenítsd meg magyarul?

Megoldás megnyitása

A deszerializáló automatikusan DateTime értéket ad; megjelenítéskor a formátum: datum.ToString("yyyy. MM. dd.") vagy a rövid dátum ToShortDateString().

4. Opcionális mező

Hogyan jelzed, hogy a születési dátum nem kötelező, és mi kerül a JSON-ba, ha nincs?

Megoldás megnyitása

Nullázható típus (DateTime?); ha nincs érték, null (vagy a mező kimarad WhenWritingNull beállításnál).

Kihívás szint

5. Polimorf lista

Egy List<Alakzat> (a 9.7 lecke) tartalmaz Teglalap és Ellipszis példányt is. Mi a baj a szerializálással, és mi a megoldás?

Megoldás megnyitása

Az alap beállítás az ősosztály típusát szerializálja: a leszármazott tulajdonságai elvesznek, és visszaolvasáskor nem derül ki a típus. Megoldás: típusjelölő mező ("tipus": "Teglalap") és saját feldolgozás, vagy a .NET újabb verzióiban a [JsonPolymorphic] és [JsonDerivedType] attribútumok.

6. Nagy JSON streamelése

Egy 300 MB-os JSON tömböt kell feldolgoznod. Mi a gond a ReadAllText + Deserialize párossal?

Megoldás megnyitása

Mindkettő a teljes szöveget (és objektumfát) a memóriába tölti. Streamelt feldolgozás: JsonSerializer.DeserializeAsyncEnumerable<T> a FileStream-ről, elemenként (a 11. fejezet aszinkron technikájával).

Gyors önellenőrzés

Válaszolj fejben, és csak utána nyisd le a választ.

1. Mi a szerializálás és a deszerializálás?

Objektum → JSON szöveg, illetve JSON szöveg → objektum.

2. Mit szerializál alapból a System.Text.Json?

A nyilvános tulajdonságokat; a mezőket nem.

3. Miért UnsafeRelaxedJsonEscaping?

Az ékezetes betűk ne \u00E1 alakban kerüljenek a fájlba; fájlnál elfogadható.

4. Miért tárolunk enumot szövegként?

Az enum sorrendje változhat; a szöveg az új érték beszúrását is kibírja.

5. Miért kell a verzió és a burkoló objektum?

Hogy a program felismerje a régi vagy újabb formátumot, és áttérjen vagy figyelmeztessen.

6. Mit tegyél hibás JSON-nál?

Jelezd a sort és a pozíciót, ne írd felül a fájlt, ajánlj biztonsági másolatot.

7. Mi a JsonIgnore szerepe?

A tulajdonság nem kerül a fájlba (számított érték, kör-hivatkozás visszamutatója).

Mit tudsz már?

  • Olvasod a JSON szerkezetét, és objektumot szerializálsz, deszerializálsz.
  • Beállítod az ékezeteket, az enumot, a dátumot, a névadást.
  • Tudod, mit ment és mit nem a System.Text.Json, és használod az attribútumokat.
  • Verziót tárolsz, és kezeled a régi és újabb fájlokat.
  • A hibás JSON-t jelzed, és nem veszítesz adatot.

Következő lecke: XML alapjai

A strukturált szöveg másik formátuma: XDocument, elemek és attribútumok, lekérdezés LINQ-val, XmlSerializer és az XML–JSON összevetése.