Migrálás a Newtonsoft.JsonSystem.Text.Json

Ez a cikk bemutatja, hogyan migrálhat System.Text.Jsona -beNewtonsoft.Json.

A System.Text.Json névtér a JavaScript Object Notation (JSON) szolgáltatásba való szerializáláshoz és deszerializáláshoz használható. A System.Text.Json kódtár a .NET Core 3.1 és újabb verziók futtatókörnyezetében található. Más cél-keretrendszerekhez telepítse a System.Text.Json NuGet-csomagot. A csomag a következőket támogatja:

  • .NET Standard 2.0-s és újabb verziók
  • .NET-keretrendszer 4.7.2-s és újabb verziók
  • .NET Core 2.0, 2.1 és 2.2

System.Text.Json elsősorban a teljesítményre, a biztonságra és a szabványoknak való megfelelőségre összpontosít. Van néhány alapvető különbség az alapértelmezett viselkedésben, és nem célja, hogy a funkciók paritása legyen.Newtonsoft.Json Egyes forgatókönyvek System.Text.Json esetében jelenleg nincs beépített funkció, de vannak javasolt áthidaló megoldások. Más forgatókönyvek esetében a kerülő megoldások nem praktikusak.

A leggyakrabban kért funkciók hozzáadásába fektetünk be. Ha az alkalmazás egy hiányzó funkciótól függ, érdemes lehet a dotnet/futtatókörnyezeti GitHub-adattárban probléma bejelentésével megtudni, hogy a forgatókönyv támogatása hozzáadható-e.

A cikk nagy része az JsonSerializer API használatáról szól, de útmutatást is tartalmaz a JsonDocument (dokumentumobjektum-modellt vagy DOM-et képviselő) Utf8JsonReaderUtf8JsonWriter és a típusok használatáról.

A Visual Basicben nem használható Utf8JsonReader, ami azt is jelenti, hogy nem írhat egyéni konvertereket. Az itt bemutatott megkerülő megoldások többségéhez egyéni konvertereket kell írnia. Egyéni konvertert írhat C# nyelven, és regisztrálhatja egy Visual Basic-projektben. További információ: Visual Basic-támogatás.

Különbségek táblázata

Az alábbi táblázat a funkciókat és System.Text.Json a megfelelőket sorolja Newtonsoft.Json fel. A megfelelők a következő kategóriákba sorolhatók:

  • ✔️ Beépített funkciók támogatják. A hasonló viselkedés megkövetelése System.Text.Json attribútum vagy globális beállítás használatát igényelheti.
  • ⚠️ Nem támogatott, de lehetséges megkerülő megoldás. A megkerülő megoldások egyéni konverterek, amelyek nem feltétlenül biztosítanak teljes paritást a funkciókhoz Newtonsoft.Json . Ezek közül néhány esetében példaként a mintakódot adhatja meg. Ha ezekre Newtonsoft.Json a funkciókra támaszkodik, az áttelepítéshez módosítani kell a .NET-objektummodelleket vagy más kódmódosításokat.
  • ❌ Nem támogatott, és a kerülő megoldás nem praktikus vagy lehetséges. Ha ezekre Newtonsoft.Json a funkciókra támaszkodik, a migrálás nem lehetséges jelentős módosítások nélkül.
Newtonsoft.Json-szolgáltatás System.Text.Json Egyenértékű
Kis- és nagybetűk érzéketlen deszerializálása alapértelmezés szerint ✔️ PropertyNameCaseInsensitive globális beállítás
Camel-case tulajdonságnevek ✔️ PropertyNamingPolicy globális beállítás
Kígyó-eset tulajdonságnevei ✔️ Kígyós eset elnevezési szabályzata
Minimális karakteres menekülés ✔️ Szigorú karakterek szökése, konfigurálható
NullValueHandling.Ignore globális beállítás ✔️ DefaultIgnoreCondition globális beállítás
Megjegyzések engedélyezése ✔️ A ReadCommentHandling globális beállítása
Záró vesszők engedélyezése ✔️ AllowTrailingCommas globális beállítás
Egyéni konverter regisztrációja ✔️ Az elsőbbségi sorrend eltérő
Alapértelmezett maximális mélység 64, konfigurálható ✔️ Alapértelmezett maximális mélység 64, konfigurálható
PreserveReferencesHandling globális beállítás ✔️ ReferenceHandling globális beállítás
Számok szerializálása vagy deszerializálása idézőjelekben ✔️ NumberHandling global setting, [JsonNumberHandling] attribútum
Deszerializálás nem módosítható osztályokhoz és szerkezetekhez ✔️ JsonConstructor, C# 9 Records
Mezők támogatása ✔️ IncludeFields globális beállítás, [JsonInclude] attribútum
DefaultValueHandling globális beállítás ✔️ DefaultIgnoreCondition globális beállítás
NullValueHandling beállítás bekapcsolva [JsonProperty] ✔️ JsonIgnore attribútum
DefaultValueHandling beállítás bekapcsolva [JsonProperty] ✔️ JsonIgnore attribútum
Deszerializálás Dictionary nem sztring típusú kulccsal ✔️ Támogatott
Nem nyilvános tulajdonságválasztók és getterek támogatása ✔️ JsonInclude attribútum
[JsonConstructor] attribútum ✔️ [JsonConstructor] attribútum
ReferenceLoopHandling globális beállítás ✔️ ReferenceHandling globális beállítás
Visszahívások ✔️ Visszahívások
NaN, Infinity, -Infinity ✔️ Támogatott
Requiredbeállítás az attribútumon [JsonProperty] ✔️ [JsonRequired] attribútum és C# szükséges módosító
DefaultContractResolver tulajdonságok figyelmen kívül hagyása ✔️ DefaultJsonTypeInfoResolver osztály
Polimorf szerializáció ✔️ [JsonDerivedType] attribútum
Polimorf deszerializálás ✔️ Típuskriminatív a [JsonDerivedType] attribútumon
Sztring enumerálási értékének deszerializálása ✔️ Sztring enumerálási értékeinek deszerializálása
MissingMemberHandling globális beállítás ✔️ Hiányzó tagok kezelése
Tulajdonságok feltöltése beállítók nélkül ✔️ Tulajdonságok feltöltése beállítók nélkül
ObjectCreationHandling globális beállítás ✔️ Tulajdonságok cseréje helyett újbóli használat
Számos típus támogatása ️ Egyes típusok egyéni konvertereket igényelnek
Késleltetett típus deszerializálása tulajdonságokra object ️ Nem támogatott, kerülő megoldás, minta
JSON-literál null deszerializálása nem null értékű értéktípusokra ️ Nem támogatott, kerülő megoldás, minta
DateTimeZoneHandling, DateFormatString beállítások ️ Nem támogatott, kerülő megoldás, minta
JsonConvert.PopulateObject Módszer ️ Nem támogatott, kerülő megoldás
System.Runtime.Serialization Attribútumok támogatása ️ Nem támogatott, kerülő megoldás, minta
JsonObjectAttribute ️ Nem támogatott, kerülő megoldás
Tulajdonságnevek engedélyezése idézőjelek nélkül A tervezés nem támogatja
Sztringértékek körüli idézőjelek engedélyezése A tervezés nem támogatja
Nem sztring JSON-értékek engedélyezése sztringtulajdonságokhoz A tervezés nem támogatja
TypeNameHandling.All globális beállítás A tervezés nem támogatja
Lekérdezések JsonPath támogatása Nem támogatott
Konfigurálható korlátok Nem támogatott
Newtonsoft.Json-szolgáltatás System.Text.Json Egyenértékű
Kis- és nagybetűk érzéketlen deszerializálása alapértelmezés szerint ✔️ PropertyNameCaseInsensitive globális beállítás
Camel-case tulajdonságnevek ✔️ PropertyNamingPolicy globális beállítás
Minimális karakteres menekülés ✔️ Szigorú karakterek szökése, konfigurálható
NullValueHandling.Ignore globális beállítás ✔️ DefaultIgnoreCondition globális beállítás
Megjegyzések engedélyezése ✔️ A ReadCommentHandling globális beállítása
Záró vesszők engedélyezése ✔️ AllowTrailingCommas globális beállítás
Egyéni konverter regisztrációja ✔️ Az elsőbbségi sorrend eltérő
Alapértelmezett maximális mélység 64, konfigurálható ✔️ Alapértelmezett maximális mélység 64, konfigurálható
PreserveReferencesHandling globális beállítás ✔️ ReferenceHandling globális beállítás
Számok szerializálása vagy deszerializálása idézőjelekben ✔️ NumberHandling global setting, [JsonNumberHandling] attribútum
Deszerializálás nem módosítható osztályokhoz és szerkezetekhez ✔️ JsonConstructor, C# 9 Records
Mezők támogatása ✔️ IncludeFields globális beállítás, [JsonInclude] attribútum
DefaultValueHandling globális beállítás ✔️ DefaultIgnoreCondition globális beállítás
NullValueHandling beállítás bekapcsolva [JsonProperty] ✔️ JsonIgnore attribútum
DefaultValueHandling beállítás bekapcsolva [JsonProperty] ✔️ JsonIgnore attribútum
Deszerializálás Dictionary nem sztring típusú kulccsal ✔️ Támogatott
Nem nyilvános tulajdonságválasztók és getterek támogatása ✔️ JsonInclude attribútum
[JsonConstructor] attribútum ✔️ [JsonConstructor] attribútum
ReferenceLoopHandling globális beállítás ✔️ ReferenceHandling globális beállítás
Visszahívások ✔️ Visszahívások
NaN, Infinity, -Infinity ✔️ Támogatott
Requiredbeállítás az attribútumon [JsonProperty] ✔️ [JsonRequired] attribútum és C# szükséges módosító
DefaultContractResolver tulajdonságok figyelmen kívül hagyása ✔️ DefaultJsonTypeInfoResolver osztály
Polimorf szerializáció ✔️ [JsonDerivedType] attribútum
Polimorf deszerializálás ✔️ Típuskriminatív a [JsonDerivedType] attribútumon
Sztring enumerálási értékének deszerializálása ✔️ Sztring enumerálási értékeinek deszerializálása
Számos típus támogatása ️ Egyes típusok egyéni konvertereket igényelnek
Késleltetett típus deszerializálása tulajdonságokra object ️ Nem támogatott, kerülő megoldás, minta
JSON-literál null deszerializálása nem null értékű értéktípusokra ️ Nem támogatott, kerülő megoldás, minta
DateTimeZoneHandling, DateFormatString beállítások ️ Nem támogatott, kerülő megoldás, minta
JsonConvert.PopulateObject Módszer ️ Nem támogatott, kerülő megoldás
ObjectCreationHandling globális beállítás ️ Nem támogatott, kerülő megoldás
Hozzáadás a gyűjteményekhez setterek nélkül ️ Nem támogatott, kerülő megoldás
Kígyó-eset tulajdonságnevei ️ Nem támogatott, kerülő megoldás
System.Runtime.Serialization Attribútumok támogatása ️ Nem támogatott, kerülő megoldás, minta
MissingMemberHandling globális beállítás ️ Nem támogatott, kerülő megoldás, minta
JsonObjectAttribute ️ Nem támogatott, kerülő megoldás
Tulajdonságnevek engedélyezése idézőjelek nélkül A tervezés nem támogatja
Sztringértékek körüli idézőjelek engedélyezése A tervezés nem támogatja
Nem sztring JSON-értékek engedélyezése sztringtulajdonságokhoz A tervezés nem támogatja
TypeNameHandling.All globális beállítás A tervezés nem támogatja
Lekérdezések JsonPath támogatása Nem támogatott
Konfigurálható korlátok Nem támogatott
Newtonsoft.Json-szolgáltatás System.Text.Json Egyenértékű
Kis- és nagybetűk érzéketlen deszerializálása alapértelmezés szerint ✔️ PropertyNameCaseInsensitive globális beállítás
Camel-case tulajdonságnevek ✔️ PropertyNamingPolicy globális beállítás
Minimális karakteres menekülés ✔️ Szigorú karakterek szökése, konfigurálható
NullValueHandling.Ignore globális beállítás ✔️ DefaultIgnoreCondition globális beállítás
Megjegyzések engedélyezése ✔️ A ReadCommentHandling globális beállítása
Záró vesszők engedélyezése ✔️ AllowTrailingCommas globális beállítás
Egyéni konverter regisztrációja ✔️ Az elsőbbségi sorrend eltérő
Alapértelmezett maximális mélység 64, konfigurálható ✔️ Alapértelmezett maximális mélység 64, konfigurálható
PreserveReferencesHandling globális beállítás ✔️ ReferenceHandling globális beállítás
Számok szerializálása vagy deszerializálása idézőjelekben ✔️ NumberHandling global setting, [JsonNumberHandling] attribútum
Deszerializálás nem módosítható osztályokhoz és szerkezetekhez ✔️ JsonConstructor, C# 9 Records
Mezők támogatása ✔️ IncludeFields globális beállítás, [JsonInclude] attribútum
DefaultValueHandling globális beállítás ✔️ DefaultIgnoreCondition globális beállítás
NullValueHandling beállítás bekapcsolva [JsonProperty] ✔️ JsonIgnore attribútum
DefaultValueHandling beállítás bekapcsolva [JsonProperty] ✔️ JsonIgnore attribútum
Deszerializálás Dictionary nem sztring típusú kulccsal ✔️ Támogatott
Nem nyilvános tulajdonságválasztók és getterek támogatása ✔️ JsonInclude attribútum
[JsonConstructor] attribútum ✔️ [JsonConstructor] attribútum
ReferenceLoopHandling globális beállítás ✔️ ReferenceHandling globális beállítás
Visszahívások ✔️ Visszahívások
NaN, Infinity, -Infinity ✔️ Támogatott
Sztring enumerálási értékének deszerializálása ✔️ Sztring enumerálási értékeinek deszerializálása
Számos típus támogatása ️ Egyes típusok egyéni konvertereket igényelnek
Polimorf szerializáció ️ Nem támogatott, kerülő megoldás, minta
Polimorf deszerializálás ️ Nem támogatott, kerülő megoldás, minta
Késleltetett típus deszerializálása tulajdonságokra object ️ Nem támogatott, kerülő megoldás, minta
JSON-literál null deszerializálása nem null értékű értéktípusokra ️ Nem támogatott, kerülő megoldás, minta
Requiredbeállítás az attribútumon [JsonProperty] ️ Nem támogatott, kerülő megoldás, minta
DefaultContractResolver tulajdonságok figyelmen kívül hagyása ️ Nem támogatott, kerülő megoldás, minta
DateTimeZoneHandling, DateFormatString beállítások ️ Nem támogatott, kerülő megoldás, minta
JsonConvert.PopulateObject Módszer ️ Nem támogatott, kerülő megoldás
ObjectCreationHandling globális beállítás ️ Nem támogatott, kerülő megoldás
Hozzáadás a gyűjteményekhez setterek nélkül ️ Nem támogatott, kerülő megoldás
Kígyó-eset tulajdonságnevei ️ Nem támogatott, kerülő megoldás
JsonObjectAttribute ️ Nem támogatott, kerülő megoldás
System.Runtime.Serialization Attribútumok támogatása Nem támogatott
MissingMemberHandling globális beállítás Nem támogatott
Tulajdonságnevek engedélyezése idézőjelek nélkül A tervezés nem támogatja
Sztringértékek körüli idézőjelek engedélyezése A tervezés nem támogatja
Nem sztring JSON-értékek engedélyezése sztringtulajdonságokhoz A tervezés nem támogatja
TypeNameHandling.All globális beállítás A tervezés nem támogatja
Lekérdezések JsonPath támogatása Nem támogatott
Konfigurálható korlátok Nem támogatott

Ez nem a funkciók teljes listája Newtonsoft.Json . A lista tartalmazza a GitHub-problémákban vagy a StackOverflow-bejegyzésekben kért forgatókönyvek nagy részét. Ha az itt felsorolt forgatókönyvek egyikéhez implementál egy áthidaló megoldást, amely jelenleg nem rendelkezik mintakóddal, és meg szeretné osztani a megoldást, válassza az Oldal lehetőséget a Lap alján található Visszajelzés szakaszban. Ez problémát okoz a dokumentáció GitHub-adattárában, és a lap Visszajelzés szakaszában is felsorolja.

Az alapértelmezett viselkedés eltérései

System.Text.Json alapértelmezés szerint szigorú, és elkerül minden találgatást vagy értelmezést a hívó nevében, hangsúlyozva a determinisztikus viselkedést. A kódtár szándékosan így lett kialakítva a teljesítmény és a biztonság érdekében. Newtonsoft.Json alapértelmezés szerint rugalmas. Ez az alapvető különbség a tervezés mögött sok az alábbi konkrét különbségek az alapértelmezett viselkedés.

Kis- és nagybetűk érzéketlen deszerializálása

A deszerializálás Newtonsoft.Json során alapértelmezés szerint egyezik a kis- és nagybetűket nem megkülönböztető tulajdonságnév. Az System.Text.Json alapértelmezett érték a kis- és nagybetűk megkülönböztetése, ami jobb teljesítményt nyújt, mivel pontos egyezést végez. A kis- és nagybetűk megkülönböztetésére vonatkozó egyeztetésről további információt a Kis- és nagybetűk megkülönböztetése tulajdonságegyeztetés című témakörben talál.

Ha közvetett módon használja System.Text.Json a ASP.NET Core-t, nem kell semmit tennie ahhoz, hogy hasonló Newtonsoft.Jsonviselkedést kapjon. ASP.NET Core megadja a teve-casing tulajdonságnevek és a kis- és nagybetűk közötti érzéketlen egyezés beállításait, amikor azt használja System.Text.Json.

ASP.NET Core alapértelmezés szerint lehetővé teszi az idézett számok deszerializálását is.

Minimális karakteres menekülés

A szerializálás Newtonsoft.Json során viszonylag megengedő a karakterek kihagyása nélkül. Vagyis nem helyettesíti őket a karakter kódpontjának \uxxxx helyével xxxx . Ahol nem menekül őket, akkor ezt úgy teszi, hogy kibocsát egy \ előtt a karakter (például " válik \"). System.Text.Json Alapértelmezés szerint több karaktert hárít el, hogy részletes védelmet nyújtson a helyek közötti szkriptelés (XSS) vagy az információfelfedés elleni támadások ellen, és ezt a hat karakterből álló sorozat használatával teszi. System.Text.JsonAlapértelmezés szerint az összes nem ASCII-karaktert feloldja, így nem kell semmit sem tennie, ha a függvényt Newtonsoft.JsonhasználjaStringEscapeHandling.EscapeNonAscii. System.Text.Json alapértelmezés szerint a HTML-bizalmas karaktereket is feloldja. Az alapértelmezett System.Text.Json viselkedés felülbírálásáról további információt a karakterkódolás testreszabása című témakörben talál.

Megjegyzések

A deszerializálás Newtonsoft.Json során alapértelmezés szerint figyelmen kívül hagyja a JSON megjegyzéseit. Alapértelmezés System.Text.Json szerint kivételeket kell kivenni a megjegyzésekből, mert az RFC 8259-specifikáció nem tartalmazza őket. A megjegyzések engedélyezéséről további információt a Megjegyzések engedélyezése és a záró vesszők című témakörben talál.

Záró vesszők

A deszerializálás Newtonsoft.Json során alapértelmezés szerint figyelmen kívül hagyja a záró vesszőket. Emellett figyelmen kívül hagyja a több záró vesszőt is (például [{"Color":"Red"},{"Color":"Green"},,]). Az System.Text.Json alapértelmezett az, hogy kivételeket ad a záró vesszőkhöz, mert az RFC 8259-specifikáció nem teszi lehetővé őket. Az elfogadásuk módjáról System.Text.Json további információt a Megjegyzések és a záró vesszők engedélyezése című témakörben talál. Nem engedélyezhet több záró vesszőt.

Konverterregisztráció elsőbbsége

Az Newtonsoft.Json egyéni konverterek regisztrációs elsőbbsége a következő:

  • Attribútum a tulajdonságon
  • Attribútum típuson
  • Konverterek gyűjteménye

Ez a sorrend azt jelenti, hogy a Converters gyűjtemény egyéni konverterét felülírja egy konverter, amely egy attribútum típusszinten történő alkalmazásával van regisztrálva. Mindkét regisztrációt felülírja egy tulajdonságszinten lévő attribútum.

Az System.Text.Json egyéni konverterek regisztrációs elsőbbsége eltérő:

  • Attribútum a tulajdonságon
  • Converters Gyűjtemény
  • Attribútum típuson

A különbség itt az, hogy a gyűjteményben lévő Converters egyéni konverter felülír egy attribútumot a típus szintjén. Az elsőbbségi sorrend mögött az a szándék áll, hogy a futásidejű módosítások felülbírálják a tervezési időt. Nem lehet megváltoztatni az elsőbbséget.

Az egyéni konverter regisztrációjáról további információt az egyéni konverter regisztrálása című témakörben talál.

Maximális mélység

A legújabb verzió Newtonsoft.Json alapértelmezés szerint 64-es maximális mélységi korláttal rendelkezik. System.Text.Json alapértelmezett korlátja 64, és a beállítással JsonSerializerOptions.MaxDepthkonfigurálható.

Ha közvetett módon használja System.Text.Json a ASP.NET Core-t, az alapértelmezett maximális mélységi korlát 32. Az alapértelmezett érték ugyanaz, mint a modellkötésnél, és a JsonOptions osztályban van beállítva.

JSON-sztringek (tulajdonságnevek és sztringértékek)

A deszerializálás Newtonsoft.Json során a tulajdonságneveket dupla idézőjelek, egyszeri idézőjelek vagy idézőjelek nélkül veszi körül. Elfogadja a sztringértékeket, amelyeket idézőjelek vagy egyszeri idézőjelek vesznek körül. Például Newtonsoft.Json elfogadja a következő JSON-t:

{
  "name1": "value",
  'name2': "value",
  name3: 'value'
}

System.Text.Jsoncsak a tulajdonságneveket és sztringértékeket fogadja el dupla idézőjelekben, mert az RFC 8259 specifikációja ezt a formátumot igényli, és ez az egyetlen érvényes JSON-formátum.

Az egyszeri idézőjelek közé zárt érték JsonException értéket eredményez, amely a következő üzenettel rendelkezik:

''' is an invalid start of a value.

Sztringtulajdonságok nem sztringértékei

Newtonsoft.Json Nem sztringértékeket fogad el, például számot vagy literálokat true , és falsea típussztring tulajdonságaira való deszerializáláshoz. Íme egy példa a JSON-ra, amely Newtonsoft.Json sikeresen deszerializálja a következő osztályt:

{
  "String1": 1,
  "String2": true,
  "String3": false
}
public class ExampleClass
{
    public string String1 { get; set; }
    public string String2 { get; set; }
    public string String3 { get; set; }
}

System.Text.Json nem deszerializálja a nem sztringértékeket sztringtulajdonságokká. A sztringmezőhöz kapott nem sztringérték jsonException értéket eredményez a következő üzenettel:

The JSON value could not be converted to System.String.

Forgatókönyvek A JsonSerializer használatával

Az alábbi forgatókönyvek némelyikét nem támogatják a beépített funkciók, de lehetséges áthidaló megoldások. A megkerülő megoldások egyéni konverterek, amelyek nem feltétlenül biztosítanak teljes paritást a funkciókhoz Newtonsoft.Json . Ezek közül néhány esetében példaként a mintakódot adhatja meg. Ha ezekre Newtonsoft.Json a funkciókra támaszkodik, az áttelepítéshez módosítani kell a .NET-objektummodelleket vagy más kódmódosításokat.

Az alábbi forgatókönyvek némelyike esetében a kerülő megoldások nem praktikusak vagy lehetségesek. Ha ezekre Newtonsoft.Json a funkciókra támaszkodik, a migrálás nem lehetséges jelentős módosítások nélkül.

Számok engedélyezése vagy írása idézőjelekben

Newtonsoft.Json szerializálhatja vagy deszerializálhatja a JSON-sztringek által képviselt számokat (idézőjelekkel körülvéve). Elfogadhatja például a következőt: {"DegreesCelsius":"23"} ahelyett {"DegreesCelsius":23}, hogy . A viselkedés System.Text.Jsonengedélyezéséhez állítsa be JsonSerializerOptions.NumberHandlingWriteAsString vagy AllowReadingFromStringhasználja a [JsonNumberHandling] attribútumot.

Ha közvetett módon használja System.Text.Json a ASP.NET Core-t, nem kell semmit tennie ahhoz, hogy hasonló Newtonsoft.Jsonviselkedést kapjon. ASP.NET Core a webes alapértelmezett értékeket adja meg a használat System.Text.Jsonsorán, a webes alapértelmezett értékek pedig az idézett számokat teszik lehetővé.

További információ: Számok engedélyezése vagy írása idézőjelekben.

A deszerializáláskor használni kívánt konstruktor megadása

Az Newtonsoft.Json[JsonConstructor] attribútum segítségével megadhatja, hogy melyik konstruktort hívja meg a POCO-ra való deszerializáláskor.

System.Text.Json[JsonConstructor] attribútummal is rendelkezik. További információ: Nem módosítható típusok és rekordok.

Tulajdonság feltételes figyelmen kívül hagyása

Newtonsoft.Json többféleképpen is feltételesen figyelmen kívül hagyhat egy tulajdonságot szerializálás vagy deszerializálás esetén:

  • DefaultContractResolver lehetővé teszi a belefoglalni vagy figyelmen kívül hagyni kívánt tulajdonságok kiválasztását tetszőleges feltételek alapján.
  • DefaultValueHandling A NullValueHandling beállításokkal JsonSerializerSettings megadhatja, hogy az összes null értékű vagy alapértelmezett érték tulajdonságot figyelmen kívül kell hagyni.
  • Az NullValueHandling attribútum és DefaultValueHandling a beállítások segítségével megadhatja azokat az [JsonProperty] egyedi tulajdonságokat, amelyeket figyelmen kívül kell hagyni null értékre vagy az alapértelmezett értékre való beállításkor.

System.Text.Json a következő módszereket biztosítja a tulajdonságok vagy mezők figyelmen kívül hagyására a szerializálás során:

A .NET 7 és újabb verzióiban emellett testre szabhatja a JSON-szerződést, hogy tetszőleges feltételek alapján figyelmen kívül hagyja a tulajdonságokat. További információ: Egyéni szerződések.

Ezekkel a beállításokkal nem hagyhatja figyelmen kívül a kiválasztott tulajdonságokat a futtatáskor kiértékelt tetszőleges feltételek alapján.

Nyilvános és nem nyilvános mezők

Newtonsoft.Json szerializálhatja és deszerializálhatja a mezőket és a tulajdonságokat.

Ebben System.Text.Jsona mezőben használja a JsonSerializerOptions.IncludeFields globális beállítást vagy a [JsonInclude] attribútumot a nyilvános mezők szerializálása vagy deszerializálása során. Példaként lásd a Mezők belefoglalása című témakört.

Objektumhivatkozások megőrzése és hurkok kezelése

Alapértelmezés szerint Newtonsoft.Json érték szerint szerializál. Ha például egy objektum két olyan tulajdonságot tartalmaz, amely ugyanarra Person az objektumra mutató hivatkozást tartalmaz, az objektum tulajdonságainak értékei Person duplikálva lesznek a JSON-ban.

Newtonsoft.JsonPreserveReferencesHandling olyan beállítással JsonSerializerSettings rendelkezik, amellyel hivatkozással szerializálható:

  • A rendszer hozzáad egy azonosító metaadatokat az első Person objektumhoz létrehozott JSON-hoz.
  • A második Person objektumhoz létrehozott JSON tulajdonságértékek helyett az adott azonosítóra mutató hivatkozást tartalmaz.

Newtonsoft.Json olyan beállítással is rendelkezik ReferenceLoopHandling , amely lehetővé teszi, hogy figyelmen kívül hagyja a körkörös hivatkozásokat ahelyett, hogy kivételt vetítenének ki.

A hivatkozások megőrzéséhez és a körkörös hivatkozások kezeléséhez állítsa a System.Text.Jsonkövetkezőre JsonSerializerOptions.ReferenceHandler : Preserve. A ReferenceHandler.Preserve beállítás egyenértékű a következő értékévelPreserveReferencesHandling.AllPreserveReferencesHandling = Newtonsoft.Json: .

A ReferenceHandler.IgnoreCycles beállítás viselkedése a következőhöz Newtonsoft.JsonReferenceLoopHandling.Ignorehasonló. Az egyik különbség az, hogy az implementáció a System.Text.Json referenciahurkokat a null JSON-jogkivonatra cseréli az objektumhivatkozás figyelmen kívül hagyása helyett. További információ: Körkörös hivatkozások figyelmen kívül hagyása.

A Newtonsoft.JsonReferenceResolverhez hasonlóan az System.Text.Json.Serialization.ReferenceResolver osztály a szerializálásra és a deszerializálásra vonatkozó hivatkozások megőrzésének viselkedését határozza meg. Hozzon létre egy származtatott osztályt az egyéni viselkedés megadásához. Példa: GuidReferenceResolver.

Néhány kapcsolódó Newtonsoft.Json funkció nem támogatott:

További információ: Hivatkozások megőrzése és körkörös hivatkozások kezelése.

Szótár nem sztringes kulccsal

Mind Newtonsoft.Json a System.Text.Json típusgyűjteményeket támogatja Dictionary<TKey, TValue>. Ebben az esetben System.Text.JsonTKey azonban primitív típusnak kell lennie, nem egyéni típusnak. További információ: Támogatott kulcstípusok.

Figyelemfelhívás

Egy olyan helyre TKey való Dictionary<TKey, TValue> deszerializálás, amely nem másként van begépelve, mint string ami biztonsági rést okozhat a fogyasztó alkalmazásban. További információ: dotnet/runtime#4761.

Beépített támogatás nélküli típusok

System.Text.Json nem nyújt beépített támogatást a következő típusokhoz:

Az egyéni konverterek olyan típusok esetén implementálhatók, amelyek nem rendelkeznek beépített támogatással.

Polimorf szerializáció

Newtonsoft.Json automatikusan elvégzi a polimorf szerializálást. A .NET 7-től System.Text.Json kezdve támogatja a polimorf szerializálást az JsonDerivedTypeAttribute attribútumon keresztül. További információ: Származtatott osztályok tulajdonságainak szerializálása.

Polimorf deszerializálás

Newtonsoft.JsonTypeNameHandling olyan beállítással rendelkezik, amely típusnév metaadatokat ad hozzá a JSON-hoz a szerializálás során. A metaadatokat a deszerializálás során a polimorf deszerializáláshoz használja. A .NET 7-től System.Text.Json kezdve a típuskriminatív információkra támaszkodik a polimorf deszerializálás végrehajtásához. Ez a metaadatok a JSON-ban lesznek kibocsátva, majd a deszerializálás során annak meghatározására szolgálnak, hogy az alaptípusra vagy származtatott típusra kell-e deszerializálni. További információ: Származtatott osztályok tulajdonságainak szerializálása.

Ha támogatni szeretné a polimorf deszerializálást a régebbi .NET-verziókban, hozzon létre egy olyan konvertert, mint az egyéni konverterek írása című példában.

Sztring enumerálási értékeinek deszerializálása

Alapértelmezés szerint nem támogatja a System.Text.Json sztringek számértékeinek deszerializálását, míg Newtonsoft.Json az igen. A következő kód például egy JsonException:

string json = "{ \"Text\": \"Hello\", \"Enum\": \"Two\" }";
var _ = JsonSerializer.Deserialize<MyObj>(json); // Throws exception.

class MyObj
{
    public string Text { get; set; } = "";
    public MyEnum Enum { get; set; }
}

enum MyEnum
{
    One,
    Two,
    Three
}

A konverter használatával azonban engedélyezheti a sztringek számértékeinek deszerializálását JsonStringEnumConverter . További információ: Enums as strings.

Objektumtulajdonságok deszerializálása

Ha Newtonsoft.Json deszerializálja a következőt Object:

  • A JSON-hasznos adatban (a kivételével null) a primitív értékek típusára következtet, és a tárolt string, long, , double, booleanvagy DateTime dobozos objektumot adja vissza. A primitív értékek egyetlen JSON-érték, például JSON-szám, sztring truefalsevagy null.
  • JObjectJArray Komplex értékeket ad vissza a JSON hasznos adataiban. Az összetett értékek JSON-kulcs-érték párok gyűjteményei a zárójeleken ({}) vagy a zárójeleken () belüli értékek listájából[] állnak. A zárójeleken vagy zárójeleken belüli tulajdonságok és értékek további tulajdonságokkal vagy értékekkel is rendelkezhetnek.
  • Nullhivatkozást ad vissza, ha a hasznos adat JSON-literált tartalmaz null .

System.Text.Json a primitív és az összetett értékekhez is dobozolt JsonElement dobozt tárol, amikor deszerializálja például a következőt Object:

  • Egy object tulajdonság.
  • Szótárérték object .
  • Tömbérték object .
  • objectGyökér .

Ugyanakkor ugyanazt kezelinull, System.Text.Json mint Newtonsoft.Json és null hivatkozást ad vissza, ha a hasznos adatban a null JSON-literál szerepel.

A tulajdonságok típuskövetkeztetésének object implementálásához hozzon létre egy konvertert, mint az egyéni konverterek írása című példában.

Null érték deszerializálása nem null értékű típusra

Newtonsoft.Json a következő forgatókönyvben nem ad kivételt:

  • NullValueHandlinga következőre van állítva:Ignore
  • A deszerializálás során a JSON null értéket tartalmaz egy nem null értékű értéktípushoz.

Ugyanebben a forgatókönyvben System.Text.Json kivételt jelent. (A megfelelő null-kezelési beállítás a JsonSerializerOptions.IgnoreNullValues = truekövetkező: System.Text.Json .)

Ha Ön a céltípus tulajdonosa, a legjobb kerülő megoldás az, ha a kérdéses tulajdonságot null értékűvé teszi (például átváltint).int?

Egy másik megkerülő megoldás a típus konverterének létrehozása, például az alábbi példa, amely a típusok null értékeit DateTimeOffset kezeli:

using System.Text.Json;
using System.Text.Json.Serialization;

namespace SystemTextJsonSamples
{
    public class DateTimeOffsetNullHandlingConverter : JsonConverter<DateTimeOffset>
    {
        public override DateTimeOffset Read(
            ref Utf8JsonReader reader,
            Type typeToConvert,
            JsonSerializerOptions options) =>
            reader.TokenType == JsonTokenType.Null
                ? default
                : reader.GetDateTimeOffset();

        public override void Write(
            Utf8JsonWriter writer,
            DateTimeOffset dateTimeValue,
            JsonSerializerOptions options) =>
            writer.WriteStringValue(dateTimeValue);
    }
}

Regisztrálja ezt az egyéni konvertert a tulajdonság egyik attribútumával vagy a konverter gyűjteményhez való Converters hozzáadásával.

Megjegyzés: Az előző konverter a null értékeket másként kezeli, mint Newtonsoft.Json az alapértelmezett értékeket megjelölő POCO-k esetében. Tegyük fel például, hogy a következő kód jelöli a célobjektumot:

public class WeatherForecastWithDefault
{
    public WeatherForecastWithDefault()
    {
        Date = DateTimeOffset.Parse("2001-01-01");
        Summary = "No summary";
    }
    public DateTimeOffset Date { get; set; }
    public int TemperatureCelsius { get; set; }
    public string Summary { get; set; }
}

Tegyük fel, hogy a következő JSON deszerializálva van az előző konverter használatával:

{
  "Date": null,
  "TemperatureCelsius": 25,
  "Summary": null
}

A deszerializálás után a Date tulajdonság értéke 1/1/0001 (default(DateTimeOffset)azaz a konstruktorban beállított érték felülírva). Ugyanazon POCO és JSON miatt a Newtonsoft.Json deszerializálás 2001.01.01-ét a Date tulajdonságban hagyná.

Deszerializálás nem módosítható osztályokhoz és szerkezetekhez

Newtonsoft.Json nem módosítható osztályokra és szerkezetekre deszerializálható, mert paraméterekkel rendelkező konstruktorokat is használhat.

A System.Text.Json[JsonConstructor] attribútum használatával adja meg a paraméteres konstruktor használatát. A C# 9 rekordjai szintén nem módosíthatók, és deszerializálási célként támogatottak. További információ: Nem módosítható típusok és rekordok.

Szükséges tulajdonságok

Ebben Newtonsoft.Jsona mezőben megadhatja, hogy egy tulajdonságra van-e szükség az [JsonProperty] attribútum beállításávalRequired. Newtonsoft.Json kivételt eredményez, ha a JSON-ban nem érkezik érték a kötelezőként megjelölt tulajdonsághoz.

A .NET 7-től kezdve használhatja a C# required módosító vagy az JsonRequiredAttribute attribútumot egy szükséges tulajdonságon. System.Text.Json kivételt eredményez, ha a JSON hasznos adata nem tartalmaz értéket a megjelölt tulajdonsághoz. További információ: Kötelező tulajdonságok.

System.Text.Json nem ad kivételt, ha a céltípus egyik tulajdonságához nem érkezik érték. Ha például van egy WeatherForecast osztálya:

public class WeatherForecast
{
    public DateTimeOffset Date { get; set; }
    public int TemperatureCelsius { get; set; }
    public string? Summary { get; set; }
}

A következő JSON hiba nélkül deszerializálva van:

{
    "TemperatureCelsius": 25,
    "Summary": "Hot"
}

Ha azt szeretné, hogy a deszerializálás sikertelen legyen, ha nincs Date tulajdonság a JSON-ban, válasszon az alábbi lehetőségek közül:

A következő mintakonverterkód kivételt jelez, ha a Date tulajdonság nincs beállítva a deszerializálás befejezése után:

using System.Text.Json;
using System.Text.Json.Serialization;

namespace SystemTextJsonSamples
{
    public class WeatherForecastRequiredPropertyConverter : JsonConverter<WeatherForecast>
    {
        public override WeatherForecast Read(
            ref Utf8JsonReader reader,
            Type type,
            JsonSerializerOptions options)
        {
            // Don't pass in options when recursively calling Deserialize.
            WeatherForecast forecast = JsonSerializer.Deserialize<WeatherForecast>(ref reader)!;

            // Check for required fields set by values in JSON
            return forecast!.Date == default
                ? throw new JsonException("Required property not received in the JSON")
                : forecast;
        }

        public override void Write(
            Utf8JsonWriter writer,
            WeatherForecast forecast, JsonSerializerOptions options)
        {
            // Don't pass in options when recursively calling Serialize.
            JsonSerializer.Serialize(writer, forecast);
        }
    }
}

Regisztrálja ezt az egyéni konvertert úgy, hogy hozzáadja a konvertert a JsonSerializerOptions.Converters gyűjteményhez.

A konverter rekurzív meghívásának ezen mintája megköveteli, hogy a konvertert ne attribútum használatával, hanem használatával JsonSerializerOptionsregisztrálja. Ha egy attribútum használatával regisztrálja a konvertert, az egyéni konverter rekurzívan meghívja magát. Az eredmény egy végtelen hurok, amely egy verem túlcsordulási kivételével végződik.

Amikor a konvertert a beállításobjektum használatával regisztrálja, elkerülheti a végtelen hurkot, ha nem adja át a beállításobjektumot rekurzív híváskor Serialize vagy Deserialize. A beállításobjektum tartalmazza a gyűjteményt Converters . Ha átadja azt az egyéni konverternek Serialize , vagy Deserializeaz egyéni konverter behívja magát, végtelen hurkot hoz létre, amely verem túlcsordulási kivételt eredményez. Ha az alapértelmezett beállítások nem megvalósíthatók, hozzon létre egy új példányt a szükséges beállításokkal. Ez a megközelítés lassú lesz, mivel minden új példány egymástól függetlenül gyorsítótáraz.

Létezik egy másik minta, amely a konvertálni kívánt osztály regisztrációjának használatával JsonConverterAttribute használható. Ebben a megközelítésben a konverterkód meghívja Serialize vagy Deserialize egy osztályon, amely a konvertálandó osztályból származik. A származtatott osztályra nincs JsonConverterAttribute alkalmazva. Az alábbi példában a következő alternatíva látható:

  • WeatherForecastWithRequiredPropertyConverterAttribute a deszerializálni kívánt osztály, és az JsonConverterAttribute azokra van alkalmazva.
  • WeatherForecastWithoutRequiredPropertyConverterAttribute az a származtatott osztály, amely nem rendelkezik a konverter attribútummal.
  • A konverterben lévő kód meghív Serialize és Deserialize be van kapcsolva WeatherForecastWithoutRequiredPropertyConverterAttribute , hogy elkerülje a végtelen hurkot. A szerializálási módszer teljesítményköltséget jelent a tulajdonságértékek extra példányosítása és másolása miatt.

Íme a WeatherForecast* típusok:

[JsonConverter(typeof(WeatherForecastRequiredPropertyConverterForAttributeRegistration))]
public class WeatherForecastWithRequiredPropertyConverterAttribute
{
    public DateTimeOffset Date { get; set; }
    public int TemperatureCelsius { get; set; }
    public string? Summary { get; set; }
}

public class WeatherForecastWithoutRequiredPropertyConverterAttribute :
    WeatherForecastWithRequiredPropertyConverterAttribute
{
}

És itt van a konverter:

using System.Text.Json;
using System.Text.Json.Serialization;

namespace SystemTextJsonSamples
{
    public class WeatherForecastRequiredPropertyConverterForAttributeRegistration :
        JsonConverter<WeatherForecastWithRequiredPropertyConverterAttribute>
    {
        public override WeatherForecastWithRequiredPropertyConverterAttribute Read(
            ref Utf8JsonReader reader,
            Type type,
            JsonSerializerOptions options)
        {
            // OK to pass in options when recursively calling Deserialize.
            WeatherForecastWithRequiredPropertyConverterAttribute forecast =
                JsonSerializer.Deserialize<WeatherForecastWithoutRequiredPropertyConverterAttribute>(
                    ref reader,
                    options)!;

            // Check for required fields set by values in JSON.
            return forecast!.Date == default
                ? throw new JsonException("Required property not received in the JSON")
                : forecast;
        }

        public override void Write(
            Utf8JsonWriter writer,
            WeatherForecastWithRequiredPropertyConverterAttribute forecast,
            JsonSerializerOptions options)
        {
            var weatherForecastWithoutConverterAttributeOnClass =
                new WeatherForecastWithoutRequiredPropertyConverterAttribute
                {
                    Date = forecast.Date,
                    TemperatureCelsius = forecast.TemperatureCelsius,
                    Summary = forecast.Summary
                };

            // OK to pass in options when recursively calling Serialize.
            JsonSerializer.Serialize(
                writer,
                weatherForecastWithoutConverterAttributeOnClass,
                options);
        }
    }
}

A szükséges tulajdonságkonverter további logikát igényel, ha olyan attribútumokat kell kezelnie, mint a [JsonIgnore] vagy különböző beállítások, például egyéni kódolók. A példakód emellett nem kezeli azokat a tulajdonságokat, amelyekhez alapértelmezett érték van beállítva a konstruktorban. Ez a megközelítés nem tesz különbséget a következő forgatókönyvek között:

  • Hiányzik egy tulajdonság a JSON-ból.
  • Egy nem null értékű típus tulajdonsága megtalálható a JSON-ban, de az érték a típus alapértelmezett értéke, például nulla a intJSON-ban.
  • A JSON-ban egy null értékű érték tulajdonsága található, de az érték null.

Feljegyzés

Ha egy ASP.NET Core-vezérlőt használSystem.Text.Json, lehetséges, hogy konverter implementálása System.Text.Json helyett használhat egy [Required] attribútumot a modellosztály tulajdonságain.

Dátumformátum megadása

Newtonsoft.Json Számos módszert kínál annak szabályozására DateTime , hogy a tulajdonságok és DateTimeOffset a típusok hogyan szerializálhatók és deszerializálhatók:

  • A DateTimeZoneHandling beállítással az összes DateTime érték szerializálható UTC-dátumként.
  • A DateFormatString beállítás és DateTime a konverterek a dátumsztringek formátumának testreszabására használhatók.

System.Text.Json Támogatja az ISO 8601-1:2019 szabványt, beleértve az RFC 3339-profilt is. Ez a formátum széles körben elterjedt, egyértelmű, és pontosan teszi a kerek utakat. Bármilyen más formátum használatához hozzon létre egy egyéni konvertert. Az alábbi konverterek például szerializálják és deszerializálják a Unix-korszakformátumot használó JSON-t időzóna-eltolással vagy anélkül (például /Date(1590863400000-0700)/ vagy /Date(1590863400000)/):

sealed class UnixEpochDateTimeOffsetConverter : JsonConverter<DateTimeOffset>
{
    static readonly DateTimeOffset s_epoch = new(1970, 1, 1, 0, 0, 0, TimeSpan.Zero);
    static readonly Regex s_regex = new("^/Date\\(([+-]*\\d+)([+-])(\\d{2})(\\d{2})\\)/$", RegexOptions.CultureInvariant);

    public override DateTimeOffset Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        string formatted = reader.GetString()!;
        Match match = s_regex.Match(formatted);

        if (
                !match.Success
                || !long.TryParse(match.Groups[1].Value, System.Globalization.NumberStyles.Integer, CultureInfo.InvariantCulture, out long unixTime)
                || !int.TryParse(match.Groups[3].Value, System.Globalization.NumberStyles.Integer, CultureInfo.InvariantCulture, out int hours)
                || !int.TryParse(match.Groups[4].Value, System.Globalization.NumberStyles.Integer, CultureInfo.InvariantCulture, out int minutes))
        {
            throw new JsonException();
        }

        int sign = match.Groups[2].Value[0] == '+' ? 1 : -1;
        TimeSpan utcOffset = new(hours * sign, minutes * sign, 0);

        return s_epoch.AddMilliseconds(unixTime).ToOffset(utcOffset);
    }

    public override void Write(Utf8JsonWriter writer, DateTimeOffset value, JsonSerializerOptions options)
    {
        long unixTime = Convert.ToInt64((value - s_epoch).TotalMilliseconds);
        TimeSpan utcOffset = value.Offset;

        string formatted = string.Create(CultureInfo.InvariantCulture, $"/Date({unixTime}{(utcOffset >= TimeSpan.Zero ? "+" : "-")}{utcOffset:hhmm})/");

        writer.WriteStringValue(formatted);
    }
}
sealed class UnixEpochDateTimeConverter : JsonConverter<DateTime>
{
    static readonly DateTime s_epoch = new(1970, 1, 1, 0, 0, 0);
    static readonly Regex s_regex = new("^/Date\\(([+-]*\\d+)\\)/$", RegexOptions.CultureInvariant);

    public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        string formatted = reader.GetString()!;
        Match match = s_regex.Match(formatted);

        if (
                !match.Success
                || !long.TryParse(match.Groups[1].Value, System.Globalization.NumberStyles.Integer, CultureInfo.InvariantCulture, out long unixTime))
        {
            throw new JsonException();
        }

        return s_epoch.AddMilliseconds(unixTime);
    }

    public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
    {
        long unixTime = Convert.ToInt64((value - s_epoch).TotalMilliseconds);

        string formatted = string.Create(CultureInfo.InvariantCulture, $"/Date({unixTime})/");
        writer.WriteStringValue(formatted);
    }
}

További információ: DateTime és DateTimeOffset támogatás a System.Text.Json.

Visszahívások

Newtonsoft.Json lehetővé teszi egyéni kód végrehajtását a szerializálási vagy deszerializálási folyamat több pontján:

  • OnDeserializing (objektum deszerializálásának megkezdésekor)
  • OnDeserialized (ha befejeződött egy objektum deszerializálása)
  • OnSerializing (amikor elkezd szerializálni egy objektumot)
  • OnSerialized (ha végzett egy objektum szerializálásával)

System.Text.Json ugyanazokat az értesítéseket teszi elérhetővé a szerializálás és a deszerializálás során. A használatukhoz implementáljon egy vagy több alábbi illesztőt a System.Text.Json.Serialization névtérből:

Íme egy példa, amely null értékű tulajdonságot keres, és üzeneteket ír a szerializálás és a deszerializálás elején és végén:

using System.Text.Json;
using System.Text.Json.Serialization;

namespace Callbacks
{
    public class WeatherForecast : 
        IJsonOnDeserializing, IJsonOnDeserialized, 
        IJsonOnSerializing, IJsonOnSerialized
    {
        public DateTime Date { get; set; }
        public int TemperatureCelsius { get; set; }
        public string? Summary { get; set; }

        void IJsonOnDeserializing.OnDeserializing() => Console.WriteLine("\nBegin deserializing");
        void IJsonOnDeserialized.OnDeserialized()
        {
            Validate();
            Console.WriteLine("Finished deserializing");
        }
        void IJsonOnSerializing.OnSerializing()
        {
            Console.WriteLine("Begin serializing");
            Validate();
        }
        void IJsonOnSerialized.OnSerialized() => Console.WriteLine("Finished serializing");

        private void Validate()
        {
            if (Summary is null)
            {
                Console.WriteLine("The 'Summary' property is 'null'.");
            }
        }
    }

    public class Program
    {
        public static void Main()
        {
            var weatherForecast = new WeatherForecast
            {
                Date = DateTime.Parse("2019-08-01"),
                TemperatureCelsius = 25,
            };

            string jsonString = JsonSerializer.Serialize(weatherForecast);
            Console.WriteLine(jsonString);

            weatherForecast = JsonSerializer.Deserialize<WeatherForecast>(jsonString);
            Console.WriteLine($"Date={weatherForecast?.Date}");
            Console.WriteLine($"TemperatureCelsius={weatherForecast?.TemperatureCelsius}");
            Console.WriteLine($"Summary={weatherForecast?.Summary}");
        }
    }
}
// output:
//Begin serializing
//The 'Summary' property is 'null'.
//Finished serializing
//{"Date":"2019-08-01T00:00:00","TemperatureCelsius":25,"Summary":null}

//Begin deserializing
//The 'Summary' property is 'null'.
//Finished deserializing
//Date=8/1/2019 12:00:00 AM
//TemperatureCelsius = 25
//Summary=

A OnDeserializing kód nem rendelkezik hozzáféréssel az új POCO-példányhoz. Az új POCO-példány deszerializáláskor történő módosításához helyezze a kódot a POCO-konstruktorba.

Nem nyilvános tulajdonságválasztók és -leválasztók

Newtonsoft.Json az attribútumon keresztül JsonProperty használhat magán- és belső tulajdonság-beállítókat és gettereket.

System.Text.JsonA [JsonInclude] attribútumon keresztül támogatja a magán- és belső tulajdonság-beállítókat és gettereket. A mintakódért lásd a nem nyilvános tulajdonsághoz tartozó tartozékokat.

Meglévő objektumok feltöltése

A JsonConvert.PopulateObject deszerializálási módszer Newtonsoft.Json egy JSON-dokumentumot egy osztály meglévő példányára deszerializál új példány létrehozása helyett. System.Text.Json mindig létrehoz egy új példányt a céltípusból az alapértelmezett nyilvános paraméter nélküli konstruktor használatával. Az egyéni konverterek deszerializálhatók egy meglévő példányra.

Tulajdonságok cseréje helyett újbóli használat

A .NET 8-tól kezdve támogatja az inicializált tulajdonságok újbóli használatát ahelyett, System.Text.Json hogy lecseréli őket. Van néhány különbség a viselkedésben, amelyről az API-javaslatban olvashat.

További információ: Inicializált tulajdonságok feltöltése.

A ObjectCreationHandling beállítás Newtonsoft.Json lehetővé teszi annak megadását, hogy a tulajdonságokban lévő objektumokat a deszerializálás során ahelyett, hogy lecserélték volna. System.Text.Json mindig lecseréli a tulajdonságokban lévő objektumokat. Az egyéni konverterek biztosítják ezt a funkciót, vagy frissíthet a .NET 8-ra, amely feltölti a funkciókat.

Tulajdonságok feltöltése beállítók nélkül

A .NET 8-tól System.Text.Json kezdve támogatja az előugró tulajdonságokat, beleértve azokat is, amelyek nem rendelkeznek beállítóval. További információ: Inicializált tulajdonságok feltöltése.

A deszerializálás során akkor is hozzáad objektumokat egy gyűjteményhez, Newtonsoft.Json ha a tulajdonság nem rendelkezik beállítóval. System.Text.Json figyelmen kívül hagyja azokat a tulajdonságokat, amelyek nem rendelkeznek beállítókkal. Az egyéni konverterek biztosíthatják ezt a funkciót, vagy frissíthet a .NET 8-ra, amely csak olvasási tulajdonságokat képes feltölteni.

Kígyós eset elnevezési szabályzata

System.Text.Json egy beépített elnevezési szabályzatot tartalmaz a kígyós esethez. Bizonyos bemenetek Newtonsoft.Json esetében azonban van néhány viselkedésbeli különbség. Az alábbi táblázat néhány ilyen különbséget mutat be a JsonNamingPolicy.SnakeCaseLower bemenetek szabályzattal való konvertálása során.

Bevitel Newtonsoft.Json Eredmény System.Text.Json Eredmény
"AB1" "a_b1" "ab1"
"SHA512Managed" "sh_a512_managed" "sha512_managed"
"abc123DEF456" "abc123_de_f456" "abc123_def456"
"KEBAB-CA Standard kiadás" "keba_b-_case" "kebab-case"

Az egyetlen beépített tulajdonságelnevezési szabályzat a System.Text.Json camel-esethez tartozik. Newtonsoft.Json átalakíthatja a tulajdonságneveket kígyós esetté. Az egyéni elnevezési szabályzatok biztosíthatják ezt a funkciót, vagy frissíthetnek a .NET 8-as vagy újabb verziójára, amely beépített kígyó-esetelnevezési szabályzatokat is tartalmaz.

System.Runtime.Szerializálási attribútumok

System.Runtime.Serialization attribútumokat, például DataContractAttribute, DataMemberAttributeés IgnoreDataMemberAttribute lehetővé teszi egy adatszerződés definiálásához. Az adatszerződés egy szolgáltatás és egy ügyfél közötti formális szerződés, amely absztrakt módon írja le a kicserélendő adatokat. Az adatszerződés pontosan meghatározza, hogy mely tulajdonságok legyenek szerializálva az exchange-hez.

System.Text.Json nem rendelkezik beépített támogatással ezekhez az attribútumokhoz. A .NET 7-től kezdve azonban egyéni típusfeloldóval is hozzáadhat támogatást. Mintául lásd a ZCS-t . DataContractResolver.

Oktális számok

Newtonsoft.Json oktális számként az első nullával rendelkező számokat kezeli. System.Text.Json nem engedélyezi a kezdő nullákat, mert az RFC 8259-specifikáció nem engedélyezi őket.

Hiányzó tagok kezelése

Ha a deszerializálandó JSON tartalmaz olyan tulajdonságokat, amelyek hiányoznak a céltípusból, Newtonsoft.Json konfigurálható kivételek kizárására. Alapértelmezés szerint System.Text.Json figyelmen kívül hagyja a JSON további tulajdonságait, kivéve, ha a [JsonExtensionData] attribútumot használja.

A .NET 8 és újabb verzióiban az alábbi eszközök egyikével beállíthatja, hogy kihagyja vagy letiltsa-e a leképezett JSON-tulajdonságokat:

JsonObjectAttribute

Newtonsoft.Jsonrendelkezik egy attribútummal, amely típusszinten alkalmazható annak szabályozására, JsonObjectAttributehogy mely tagok szerializálva vannak, hogyan null kezelik az értékeket, és hogy minden tagra szükség van-e. System.Text.Json nem rendelkezik olyan attribútummal, amely alkalmazható egy típusra. Bizonyos viselkedések, például null az értékkezelés esetében ugyanezt a viselkedést konfigurálhatja globálisan JsonSerializerOptions vagy egyenként az egyes tulajdonságokon.

Vegye figyelembe az alábbi példát, amely azt határozza Newtonsoft.Json.JsonObjectAttribute meg, hogy az összes null tulajdonságot figyelmen kívül kell hagyni:

[JsonObject(ItemNullValueHandling = NullValueHandling.Ignore)]
public class Person { ... }

Ebben System.Text.Jsonaz esetben beállíthatja az összes típus és tulajdonság viselkedését:

JsonSerializerOptions options = new()
{
    DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
};

string json = JsonSerializer.Serialize<Person>(person, options);

Vagy az egyes tulajdonságok viselkedését külön is beállíthatja:

public class Person
{
    [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
    public string? Name { get; set; }

    [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
    public int? Age { get; set; }
}

Ezután tekintse meg az alábbi példát, amely azt határozza Newtonsoft.Json.JsonObjectAttribute meg, hogy az összes tagtulajdonságnak jelen kell lennie a JSON-ban:

[JsonObject(ItemRequired = Required.Always)]
public class Person { ... }

Ugyanezt a viselkedést System.Text.Json úgy érheti el, hogy hozzáadja a C# required módosítóját vagy az JsonRequiredAttributeegyes tulajdonságokhoz. További információ: Kötelező tulajdonságok.

public class Person
{
    [JsonRequired]
    public string? Name { get; set; }

    public required int? Age { get; set; }
}

TraceWriter

Newtonsoft.Json lehetővé teszi a hibakeresést a TraceWriter szerializálás vagy deszerializálás által létrehozott naplók megtekintéséhez. System.Text.Json nem végez naplózást.

JsonDocument és JsonElement a JTokenhez képest (például JObject, JArray)

System.Text.Json.JsonDocumentLehetővé teszi egy írásvédett dokumentumobjektum-modell (DOM) elemzését és összeállítását a meglévő JSON-hasznos adatokból. A DOM véletlenszerű hozzáférést biztosít az adatokhoz egy JSON-hasznos adatban. A hasznos adatokat alkotó JSON-elemek a típuson keresztül JsonElement érhetők el. A JsonElement típus API-kat biztosít a JSON-szöveg gyakori .NET-típusokká alakításához. JsonDocument tulajdonságot RootElement tesz elérhetővé.

A .NET 6-tól kezdve elemezheti és létrehozhat egy mutable DOM-ot a meglévő JSON-hasznos adatokból a JsonNode névtér típusának és más típusainak System.Text.Json.Nodes használatával. További információ: Használat JsonNode.

A JsonDocument IDisposable

JsonDocument memóriabeli nézetet készít az adatokról egy készletezett pufferbe. Ezért a típus a JsonDocument használatban lévő blokkokkal IDisposable ellentétben vagy azoktól Newtonsoft.Jsoneltérően JObjectJArray implementálható, és azt egy használatban lévő blokkban kell használni. További információ: JsonDocument is IDisposable.

A JsonDocument írásvédett

A System.Text.Json DOM nem tud JSON-elemeket hozzáadni, eltávolítani vagy módosítani. Így lett kialakítva a teljesítményhez, és csökkenti a JSON hasznos adatméretek (azaz < 1 MB) elemzéséhez szükséges foglalásokat.

A JsonElement egy szakszervezeti struktúra

JsonDocumentRootElement a JSON-elemeket magában foglaló egyesítési struktúratípus, amely a típustulajdonságokat JsonElementteszi elérhetővé. Newtonsoft.Json dedikált hierarchikus típusokat használ, például JObject:JArray, JTokenstb. JsonElement Ez az, amit kereshet és számba vehet, és a JsonElement JSON-elemeket .NET-típusokká alakíthatja.

A .NET 6-tól JsonNode kezdve használhat típusokat és típusokat a névtérben, amely megfelel a System.Text.Json.Nodes (ésJToken)JArray névtérnekJObject. További információ: Használat JsonNode.

JsonDocument és JsonElement keresése alelemekre

A JSON-jogkivonatok használata JObject vagy JArray használata Newtonsoft.Json általában viszonylag gyors, mert bizonyos szótárakban keresnek. Összehasonlításképpen a kereséshez szekvenciális keresésre van szükség a tulajdonságok között JsonElement , ezért viszonylag lassúak (például használat esetén TryGetProperty). System.Text.Json úgy lett kialakítva, hogy a keresési idő helyett minimalizálja a kezdeti elemzési időt. További információ: JsonDocument és JsonElement alelemek keresése.

Utf8JsonReader és JsonTextReader

System.Text.Json.Utf8JsonReaderAz UTF-8 kódolású JSON-szövegek nagy teljesítményű, alacsony kiosztású, előre csak továbbítható olvasója, amely ReadOnlySpan<bájtból> vagy ReadOnlySequence<bájtból >olvasható. Ez Utf8JsonReader egy alacsony szintű típus, amely egyéni elemzők és deszerializálók készítésére használható.

Az Utf8JsonReader egy ref struct

A JsonTextReader be egy Newtonsoft.Json osztály. A Utf8JsonReader típus abban különbözik, hogy ez egy refstruktúra. További információkért tekintse meg az Utf8JsonReader refstruktúrakorlátozásait.

Null értékek beolvasása null értékű értéktípusokba

Newtonsoft.Jsonolyan API-kat biztosít, amelyek visszaadják például azt, amely egy Nullbool?TokenType .ReadAsBooleanNullable<T> A beépített System.Text.Json API-k csak nem null értékű értéktípusokat ad vissza. További információ: Null értékek beolvasása null értékű értéktípusokba.

Több cél a JSON olvasásához

Ha továbbra is használnia Newtonsoft.Json kell bizonyos cél-keretrendszereket, több célrendszert is használhat, és két implementációval rendelkezhet. Ez azonban nem triviális, és némi #ifdefs és forrás-duplikációt igényelne. A lehető legtöbb kód megosztásának egyik módja egy ref struct burkoló Utf8JsonReader létrehozása.Newtonsoft.Json.JsonTextReader Ez a burkoló egységesíti a nyilvános felületet, miközben elkülöníti a viselkedési különbségeket. Ez lehetővé teszi a módosítások elkülönítését elsősorban a típus felépítésében, valamint az új típus hivatkozás alapján történő átadását. Ezt a mintát követi a Microsoft.Extensions.DependencyModel kódtár:

Utf8JsonWriter vs. JsonTextWriter

System.Text.Json.Utf8JsonWriteraz UTF-8 kódolású JSON-szövegek írásának nagy teljesítményű módja a gyakori .NET-típusokból, például Stringa DateTime. Int32 Az író egy alacsony szintű típus, amely egyéni szerializálók készítésére használható.

Nyers értékek írása

Newtonsoft.Json olyan metódussal WriteRawValue rendelkezik, amely nyers JSON-t ír, ahol érték várható. System.Text.Json közvetlen megfelelője: Utf8JsonWriter.WriteRawValue. További információ: Nyers JSON írása.

JSON-formátum testreszabása

JsonTextWriter a következő beállításokat tartalmazza, amelyekhez Utf8JsonWriter nincs egyenértékű:

  • QuoteChar – A sztringértékek körülöleléséhez használandó karaktert adja meg. Utf8JsonWriter mindig dupla idézőjeleket használ.
  • QuoteName – Azt határozza meg, hogy idézőjelekkel kell-e körülvenni a tulajdonságneveket. Utf8JsonWriter mindig idézőjelekkel veszi körül őket.

A .NET 9-től kezdve testre szabhatja a behúzási karaktert és a méretet Utf8JsonWriter a JsonWriterOptions szerkezet által közzétett beállítások használatához:

  • JsonWriterOptions.IndentCharacter
  • JsonWriterOptions.IndentSize

JsonTextWriter a következő beállításokat tartalmazza, amelyekhez Utf8JsonWriter nincs egyenértékű:

  • Behúzás – Megadja, hogy hány karaktert kell behúzni. Utf8JsonWriter mindig 2 karakterből áll.
  • Behúzásdiagram – A behúzáshoz használandó karaktert adja meg. Utf8JsonWriter mindig szóközt használ.
  • QuoteChar – A sztringértékek körülöleléséhez használandó karaktert adja meg. Utf8JsonWriter mindig dupla idézőjeleket használ.
  • QuoteName – Azt határozza meg, hogy idézőjelekkel kell-e körülvenni a tulajdonságneveket. Utf8JsonWriter mindig idézőjelekkel veszi körül őket.

Nincsenek olyan áthidaló megoldások, amelyek lehetővé tennék az ilyen módon létrehozott Utf8JsonWriter JSON testreszabását.

Írási idő, Uri vagy karakterértékek

JsonTextWriterMetódusokat biztosít WriteValue a TimeSpan, az Uri és a char értékekhez. Utf8JsonWriter nem rendelkezik egyenértékű metódusok. Ehelyett formázza ezeket az értékeket sztringekként (például meghívással ToString()) és hívásként WriteStringValue.

Több cél JSON írásához

Ha továbbra is használnia Newtonsoft.Json kell bizonyos cél-keretrendszereket, több célrendszert is használhat, és két implementációval rendelkezhet. Ez azonban nem triviális, és némi #ifdefs és forrás-duplikációt igényelne. A lehető legtöbb kód megosztásának egyik módja egy burkoló Utf8JsonWriter létrehozása.Newtonsoft.Json.JsonTextWriter Ez a burkoló egységesíti a nyilvános felületet, miközben elkülöníti a viselkedési különbségeket. Ez lehetővé teszi, hogy elkülönítse a változásokat elsősorban a típus felépítésében. A Microsoft.Extensions.DependencyModel kódtár a következő:

TypeNameHandling.All nem támogatott

A -equivalent funkció System.Text.Json kizárása TypeNameHandling.Allszándékos volt. A webalkalmazások biztonsági réseinek gyakori forrása, hogy lehetővé teszi a JSON hasznos adatainak megadását. A konfigurálás Newtonsoft.JsonTypeNameHandling.All lehetővé teszi, hogy a távoli ügyfél beágyazzon egy teljes végrehajtható alkalmazást a JSON hasznos adatai közé, így a deszerializálás során a webalkalmazás kinyeri és futtatja a beágyazott kódot. További információkért lásd a 13. JSON-támadást, a PowerPointot , pénteken pedig a 13. JSON-támadás részleteit.

A JSON-elérési út lekérdezései nem támogatottak

A JsonDocument DOM nem támogatja a JSON-elérési út használatával történő lekérdezést.

JsonNode A DOM-ban minden JsonNode példány rendelkezik egy GetPath metódussal, amely visszaadja az adott csomópont elérési útját. A JSON Path lekérdezési sztringeken alapuló lekérdezések kezelésére azonban nincs beépített API.

További információ: dotnet/runtime #31068 GitHub-probléma.

Egyes korlátok nem konfigurálhatók

System.Text.Json Bizonyos értékekre nem módosítható korlátokat állít be, például a karakterek maximális tokenméretét (166 MB) és a 64-es alapértéket (125 MB). További információ JsonConstants : forráskód és GitHub-probléma dotnet/runtime #39953.

NaN, Infinity, -Infinity

A Newtonsoft elemzi a NaNJSON-sztring Infinity-Infinity jogkivonatait. With System.Text.Json, use JsonNumberHandling.AllowNamedFloatingPointLiterals. A beállítás használatáról további információt a számok engedélyezése vagy írása idézőjelekben című témakörben talál.

További erőforrások