Migreren van Newtonsoft.Json naar System.Text.Json

In dit artikel wordt beschreven hoe u migreert van Newtonsoft.Json naar System.Text.Json.

De System.Text.Json naamruimte biedt functionaliteit voor het serialiseren naar en deserialiseren van JavaScript Object Notation (JSON). De System.Text.Json bibliotheek is opgenomen in de runtime voor .NET Core 3.1 en latere versies. Installeer het System.Text.Json NuGet-pakket voor andere doelframeworks. Het pakket ondersteunt:

  • .NET Standard 2.0 en latere versies
  • .NET Framework 4.7.2 en nieuwere versies
  • .NET Core 2.0, 2.1 en 2.2

System.Text.Json is voornamelijk gericht op naleving van prestaties, beveiliging en standaarden. Het heeft enkele belangrijke verschillen in het standaardgedrag en heeft geen doel om functiepariteit met Newtonsoft.Json. Voor sommige scenario's System.Text.Json heeft momenteel geen ingebouwde functionaliteit, maar er zijn aanbevolen tijdelijke oplossingen. Voor andere scenario's zijn tijdelijke oplossingen niet praktisch.

We investeren in het toevoegen van de functies die het vaakst worden aangevraagd. Als uw toepassing afhankelijk is van een ontbrekende functie, kunt u een probleem indienen in de GitHub-opslagplaats dotnet/runtime om erachter te komen of ondersteuning voor uw scenario kan worden toegevoegd.

Het grootste deel van dit artikel gaat over het gebruik van de JsonSerializer API, maar bevat ook richtlijnen voor het gebruik van het JsonDocument (dat het documentobjectmodel of dom vertegenwoordigt) Utf8JsonReaderen Utf8JsonWriter typen.

In Visual Basic kunt u geen aangepaste conversieprogramma's schrijven Utf8JsonReader. Voor de meeste tijdelijke oplossingen die hier worden weergegeven, moet u aangepaste conversieprogramma's schrijven. U kunt een aangepast conversieprogramma schrijven in C# en deze registreren in een Visual Basic-project. Zie Visual Basic-ondersteuning voor meer informatie.

Tabel met verschillen

De volgende tabel bevat Newtonsoft.Json functies en System.Text.Json equivalenten. De equivalenten vallen in de volgende categorieën:

  • ✔️ Ondersteund door ingebouwde functionaliteit. Voor het ophalen van vergelijkbaar gedrag System.Text.Json is mogelijk het gebruik van een kenmerk of globale optie vereist.
  • ⚠ϑ Niet ondersteund, maar tijdelijke oplossing is mogelijk. De tijdelijke oplossingen zijn aangepaste conversieprogramma's, die mogelijk geen volledige pariteit met Newtonsoft.Json functionaliteit bieden. Voor sommige hiervan wordt voorbeeldcode gegeven als voorbeelden. Als u van deze Newtonsoft.Json functies afhankelijk bent, zijn voor migratie wijzigingen in uw .NET-objectmodellen of andere codewijzigingen vereist.
  • ❌ Niet ondersteund en tijdelijke oplossing is niet praktisch of mogelijk. Als u van deze Newtonsoft.Json functies afhankelijk bent, is migratie niet mogelijk zonder belangrijke wijzigingen.
Newtonsoft.Json-functie System.Text.Json Gelijkwaardig
Hoofdlettergevoelige deserialisatie is standaard ✔️ Globale instelling PropertyNameCaseInsensitive
Namen van eigenschappen van camel-case ✔️ Globale instelling PropertyNamingPolicy
Namen van slang-case-eigenschappen ✔️ Naamgevingsbeleid voor slangencases
Minimale escapetekens ✔️ Strikt teken ontsnappen, configureerbaar
NullValueHandling.Ignore algemene instelling ✔️ Algemene optie DefaultIgnoreCondition
Opmerkingen toestaan ✔️ Algemene instelling ReadCommentHandling
Volgkomma's toestaan ✔️ Globale instelling AllowTrailingCommas
Registratie van aangepaste conversieprogramma's ✔️ Volgorde van prioriteit verschilt
Standaard maximale diepte 64, configureerbaar ✔️ Standaard maximale diepte 64, configureerbaar
PreserveReferencesHandling algemene instelling ✔️ Algemene instelling ReferenceHandling
Getallen in aanhalingstekens serialiseren of deserialiseren ✔️ Algemene instelling NumberHandling, kenmerk [JsonNumberHandling]
Deserialiseren naar onveranderbare klassen en structs ✔️ JsonConstructor, C# 9 Records
Ondersteuning voor velden ✔️ Algemene instelling IncludeFields, kenmerk [JsonInclude]
DefaultValueHandling algemene instelling ✔️ Algemene instelling DefaultIgnoreCondition
NullValueHandling instellen op [JsonProperty] ✔️ JsonIgnore-kenmerk
DefaultValueHandling instellen op [JsonProperty] ✔️ JsonIgnore-kenmerk
Deserialiseren Dictionary met niet-tekenreekssleutel ✔️ Ondersteund
Ondersteuning voor niet-openbare eigenschappensetters en getters ✔️ JsonInclude-kenmerk
[JsonConstructor]-kenmerk ✔️ [JsonConstructor] kenmerk
ReferenceLoopHandling algemene instelling ✔️ Algemene instelling ReferenceHandling
Callbacks ✔️ Callbacks
NaN, Infinity, -Infinity ✔️ Ondersteund
Required instellen op [JsonProperty] kenmerk ✔️ [JsonRequired] kenmerk en C# vereiste modifier
DefaultContractResolver eigenschappen negeren ✔️ Klasse DefaultJsonTypeInfoResolver
Polymorfische serialisatie ✔️ [JsonDerivedType] kenmerk
Polymorfische deserialisatie ✔️ Type discriminator op het kenmerk [JsonDerivedType]
Opsommingswaarde van tekenreeks deserialiseren ✔️ Tekenreekswaarden deserialiseren
MissingMemberHandling algemene instelling ✔️ Ontbrekende leden verwerken
Eigenschappen zonder setters vullen ✔️ Eigenschappen zonder setters vullen
ObjectCreationHandling algemene instelling ✔️ Eigenschappen opnieuw gebruiken in plaats van eigenschappen te vervangen
Ondersteuning voor een breed scala aan typen Sommige typen vereisen aangepaste conversieprogramma's
Afgeleid type deserialiseren naar object eigenschappen Niet ondersteund, tijdelijke oplossing, voorbeeld
Deserialize JSON null literal to non-nullable value types Niet ondersteund, tijdelijke oplossing, voorbeeld
DateTimeZoneHandling, DateFormatString instellingen Niet ondersteund, tijdelijke oplossing, voorbeeld
JsonConvert.PopulateObject Methode ⚠ϑ Niet ondersteund, tijdelijke oplossing
Ondersteuning voor System.Runtime.Serialization kenmerken Niet ondersteund, tijdelijke oplossing, voorbeeld
JsonObjectAttribute ⚠ϑ Niet ondersteund, tijdelijke oplossing
Eigenschapsnamen zonder aanhalingstekens toestaan Niet ondersteund door ontwerp
Enkele aanhalingstekens rond tekenreekswaarden toestaan Niet ondersteund door ontwerp
JSON-waarden van niet-tekenreeksen toestaan voor tekenreekseigenschappen Niet ondersteund door ontwerp
TypeNameHandling.All algemene instelling Niet ondersteund door ontwerp
Ondersteuning voor JsonPath query's Niet ondersteund
Configureerbare limieten Niet ondersteund
Newtonsoft.Json-functie System.Text.Json Gelijkwaardig
Hoofdlettergevoelige deserialisatie is standaard ✔️ Globale instelling PropertyNameCaseInsensitive
Namen van eigenschappen van camel-case ✔️ Globale instelling PropertyNamingPolicy
Minimale escapetekens ✔️ Strikt teken ontsnappen, configureerbaar
NullValueHandling.Ignore algemene instelling ✔️ Algemene optie DefaultIgnoreCondition
Opmerkingen toestaan ✔️ Algemene instelling ReadCommentHandling
Volgkomma's toestaan ✔️ Globale instelling AllowTrailingCommas
Registratie van aangepaste conversieprogramma's ✔️ Volgorde van prioriteit verschilt
Standaard maximale diepte 64, configureerbaar ✔️ Standaard maximale diepte 64, configureerbaar
PreserveReferencesHandling algemene instelling ✔️ Algemene instelling ReferenceHandling
Getallen in aanhalingstekens serialiseren of deserialiseren ✔️ Algemene instelling NumberHandling, kenmerk [JsonNumberHandling]
Deserialiseren naar onveranderbare klassen en structs ✔️ JsonConstructor, C# 9 Records
Ondersteuning voor velden ✔️ Algemene instelling IncludeFields, kenmerk [JsonInclude]
DefaultValueHandling algemene instelling ✔️ Algemene instelling DefaultIgnoreCondition
NullValueHandling instellen op [JsonProperty] ✔️ JsonIgnore-kenmerk
DefaultValueHandling instellen op [JsonProperty] ✔️ JsonIgnore-kenmerk
Deserialiseren Dictionary met niet-tekenreekssleutel ✔️ Ondersteund
Ondersteuning voor niet-openbare eigenschappensetters en getters ✔️ JsonInclude-kenmerk
[JsonConstructor]-kenmerk ✔️ [JsonConstructor] kenmerk
ReferenceLoopHandling algemene instelling ✔️ Algemene instelling ReferenceHandling
Callbacks ✔️ Callbacks
NaN, Infinity, -Infinity ✔️ Ondersteund
Required instellen op [JsonProperty] kenmerk ✔️ [JsonRequired] kenmerk en C# vereiste modifier
DefaultContractResolver eigenschappen negeren ✔️ Klasse DefaultJsonTypeInfoResolver
Polymorfische serialisatie ✔️ [JsonDerivedType] kenmerk
Polymorfische deserialisatie ✔️ Type discriminator op het kenmerk [JsonDerivedType]
Opsommingswaarde van tekenreeks deserialiseren ✔️ Tekenreekswaarden deserialiseren
Ondersteuning voor een breed scala aan typen Sommige typen vereisen aangepaste conversieprogramma's
Afgeleid type deserialiseren naar object eigenschappen Niet ondersteund, tijdelijke oplossing, voorbeeld
Deserialize JSON null literal to non-nullable value types Niet ondersteund, tijdelijke oplossing, voorbeeld
DateTimeZoneHandling, DateFormatString instellingen Niet ondersteund, tijdelijke oplossing, voorbeeld
JsonConvert.PopulateObject Methode ⚠ϑ Niet ondersteund, tijdelijke oplossing
ObjectCreationHandling algemene instelling ⚠ϑ Niet ondersteund, tijdelijke oplossing
Toevoegen aan verzamelingen zonder setters ⚠ϑ Niet ondersteund, tijdelijke oplossing
Namen van slang-case-eigenschappen ⚠ϑ Niet ondersteund, tijdelijke oplossing
Ondersteuning voor System.Runtime.Serialization kenmerken Niet ondersteund, tijdelijke oplossing, voorbeeld
MissingMemberHandling algemene instelling Niet ondersteund, tijdelijke oplossing, voorbeeld
JsonObjectAttribute ⚠ϑ Niet ondersteund, tijdelijke oplossing
Eigenschapsnamen zonder aanhalingstekens toestaan Niet ondersteund door ontwerp
Enkele aanhalingstekens rond tekenreekswaarden toestaan Niet ondersteund door ontwerp
JSON-waarden van niet-tekenreeksen toestaan voor tekenreekseigenschappen Niet ondersteund door ontwerp
TypeNameHandling.All algemene instelling Niet ondersteund door ontwerp
Ondersteuning voor JsonPath query's Niet ondersteund
Configureerbare limieten Niet ondersteund
Newtonsoft.Json-functie System.Text.Json Gelijkwaardig
Hoofdlettergevoelige deserialisatie is standaard ✔️ Globale instelling PropertyNameCaseInsensitive
Namen van eigenschappen van camel-case ✔️ Globale instelling PropertyNamingPolicy
Minimale escapetekens ✔️ Strikt teken ontsnappen, configureerbaar
NullValueHandling.Ignore algemene instelling ✔️ Algemene optie DefaultIgnoreCondition
Opmerkingen toestaan ✔️ Algemene instelling ReadCommentHandling
Volgkomma's toestaan ✔️ Globale instelling AllowTrailingCommas
Registratie van aangepaste conversieprogramma's ✔️ Volgorde van prioriteit verschilt
Standaard maximale diepte 64, configureerbaar ✔️ Standaard maximale diepte 64, configureerbaar
PreserveReferencesHandling algemene instelling ✔️ Algemene instelling ReferenceHandling
Getallen in aanhalingstekens serialiseren of deserialiseren ✔️ Algemene instelling NumberHandling, kenmerk [JsonNumberHandling]
Deserialiseren naar onveranderbare klassen en structs ✔️ JsonConstructor, C# 9 Records
Ondersteuning voor velden ✔️ Algemene instelling IncludeFields, kenmerk [JsonInclude]
DefaultValueHandling algemene instelling ✔️ Algemene instelling DefaultIgnoreCondition
NullValueHandling instellen op [JsonProperty] ✔️ JsonIgnore-kenmerk
DefaultValueHandling instellen op [JsonProperty] ✔️ JsonIgnore-kenmerk
Deserialiseren Dictionary met niet-tekenreekssleutel ✔️ Ondersteund
Ondersteuning voor niet-openbare eigenschappensetters en getters ✔️ JsonInclude-kenmerk
[JsonConstructor]-kenmerk ✔️ [JsonConstructor] kenmerk
ReferenceLoopHandling algemene instelling ✔️ Algemene instelling ReferenceHandling
Callbacks ✔️ Callbacks
NaN, Infinity, -Infinity ✔️ Ondersteund
Opsommingswaarde van tekenreeks deserialiseren ✔️ Tekenreekswaarden deserialiseren
Ondersteuning voor een breed scala aan typen Sommige typen vereisen aangepaste conversieprogramma's
Polymorfische serialisatie Niet ondersteund, tijdelijke oplossing, voorbeeld
Polymorfische deserialisatie Niet ondersteund, tijdelijke oplossing, voorbeeld
Afgeleid type deserialiseren naar object eigenschappen Niet ondersteund, tijdelijke oplossing, voorbeeld
Deserialize JSON null literal to non-nullable value types Niet ondersteund, tijdelijke oplossing, voorbeeld
Required instellen op [JsonProperty] kenmerk Niet ondersteund, tijdelijke oplossing, voorbeeld
DefaultContractResolver eigenschappen negeren Niet ondersteund, tijdelijke oplossing, voorbeeld
DateTimeZoneHandling, DateFormatString instellingen Niet ondersteund, tijdelijke oplossing, voorbeeld
JsonConvert.PopulateObject Methode ⚠ϑ Niet ondersteund, tijdelijke oplossing
ObjectCreationHandling algemene instelling ⚠ϑ Niet ondersteund, tijdelijke oplossing
Toevoegen aan verzamelingen zonder setters ⚠ϑ Niet ondersteund, tijdelijke oplossing
Namen van slang-case-eigenschappen ⚠ϑ Niet ondersteund, tijdelijke oplossing
JsonObjectAttribute ⚠ϑ Niet ondersteund, tijdelijke oplossing
Ondersteuning voor System.Runtime.Serialization kenmerken Niet ondersteund
MissingMemberHandling algemene instelling Niet ondersteund
Eigenschapsnamen zonder aanhalingstekens toestaan Niet ondersteund door ontwerp
Enkele aanhalingstekens rond tekenreekswaarden toestaan Niet ondersteund door ontwerp
JSON-waarden van niet-tekenreeksen toestaan voor tekenreekseigenschappen Niet ondersteund door ontwerp
TypeNameHandling.All algemene instelling Niet ondersteund door ontwerp
Ondersteuning voor JsonPath query's Niet ondersteund
Configureerbare limieten Niet ondersteund

Dit is geen volledige lijst met Newtonsoft.Json functies. De lijst bevat veel van de scenario's die zijn aangevraagd in GitHub-problemen of StackOverflow-berichten . Als u een tijdelijke oplossing implementeert voor een van de hier vermelde scenario's die momenteel geen voorbeeldcode hebben en als u uw oplossing wilt delen, selecteert u deze pagina in de sectie Feedback onder aan deze pagina. Dit maakt een probleem in de GitHub-opslagplaats van deze documentatie en vermeldt dit ook in de sectie Feedback op deze pagina.

Verschillen in standaardgedrag

System.Text.Json is standaard strikt en vermijdt elke schatting of interpretatie namens de beller, waarbij deterministisch gedrag wordt benadrukt. De bibliotheek is opzettelijk ontworpen op deze manier voor prestaties en beveiliging. Newtonsoft.Json is standaard flexibel. Dit fundamentele verschil in ontwerp ligt achter een groot aantal van de volgende specifieke verschillen in standaardgedrag.

Hoofdlettergevoelige deserialisatie

Tijdens de deserialisatie komt Newtonsoft.Json standaard de naam van de niet-hoofdlettergevoelige eigenschap overeen. De System.Text.Json standaardwaarde is hoofdlettergevoelig, wat betere prestaties biedt, omdat het een exacte overeenkomst doet. Zie Hoofdlettergevoelige eigenschapskoppeling voor informatie over het uitvoeren van niet-hoofdlettergevoelige overeenkomsten.

Als u System.Text.Json indirect gebruikmaakt van ASP.NET Core, hoeft u niets te doen om gedrag te krijgen, zoals Newtonsoft.Json. ASP.NET Core geeft de instellingen op voor eigenschappennamen van kameelbehuizing en hoofdlettergevoelige overeenkomsten wanneer deze wordt gebruikt System.Text.Json.

ASP.NET Core schakelt ook standaard deserialiseren van getallen tussen aangestelde waarden in.

Minimale escapetekens

Tijdens de serialisatie Newtonsoft.Json is het relatief permissief om tekens door te laten zonder ze te ontsnappen. Dat wil gezegd, het vervangt ze niet door \uxxxx waar xxxx het codepunt van het teken is. Waar het aan ze ontsnapt, doet het dit door een \ voor het teken te verzenden (bijvoorbeeld " ).\" System.Text.Json escapes standaard meer tekens om diepgaande verdedigingsbeveiliging te bieden tegen XSS-aanvallen (cross-site scripting) of aanvallen met openbaarmaking van informatie. Dit doet u met behulp van de reeks van zes tekens. System.Text.Json escapes alle niet-ASCII-tekens standaard, dus u hoeft niets te doen als u StringEscapeHandling.EscapeNonAscii in Newtonsoft.Json. System.Text.Json escapen ook html-gevoelige tekens, standaard. Zie Tekencodering aanpassen voor informatie over het overschrijven van het standaardgedrag System.Text.Json.

Opmerkingen

Tijdens de deserialisatie Newtonsoft.Json worden opmerkingen in de JSON standaard genegeerd. De System.Text.Json standaardinstelling is uitzonderingen voor opmerkingen te genereren omdat de RFC 8259-specificatie deze niet bevat. Zie Opmerkingen en volgkomma's toestaan voor informatie over het toestaan van opmerkingen.

Volgkomma's

Tijdens de deserialisatie Newtonsoft.Json worden volgkomma's standaard genegeerd. Het negeert ook meerdere volgkomma's (bijvoorbeeld [{"Color":"Red"},{"Color":"Green"},,]). De System.Text.Json standaardinstelling is uitzonderingen voor volgkomma's te genereren omdat de RFC 8259-specificatie ze niet toestaat. Zie Opmerkingen en volgkomma's toestaan voor informatie over hoe System.Text.Json u deze accepteert. Er is geen manier om meerdere volgkomma's toe te staan.

Prioriteit van conversieprogrammaregistratie

De Newtonsoft.Json registratieprioriteit voor aangepaste conversieprogramma's is als volgt:

Deze volgorde betekent dat een aangepast conversieprogramma in de Converters verzameling wordt overschreven door een conversieprogramma dat is geregistreerd door een kenmerk toe te passen op het typeniveau. Beide registraties worden overschreven door een kenmerk op eigenschapsniveau.

De System.Text.Json registratieprioriteit voor aangepaste conversieprogramma's verschilt:

  • Kenmerk op eigenschap
  • Converters Collectie
  • Kenmerk op type

Het verschil hier is dat een aangepast conversieprogramma in de Converters verzameling een kenmerk op typeniveau overschrijft. De bedoeling achter deze volgorde van prioriteit is om runtimewijzigingen te maken die de ontwerptijd overschrijven. Er is geen manier om de prioriteit te wijzigen.

Zie Een aangepast conversieprogramma registreren voor meer informatie over de registratie van aangepaste conversieprogramma's.

Maximale diepte

De nieuwste versie van Newtonsoft.Json de app heeft standaard een maximale dieptelimiet van 64. System.Text.Json heeft ook een standaardlimiet van 64 en kan worden geconfigureerd door deze in te stellen JsonSerializerOptions.MaxDepth.

Als u System.Text.Json indirect gebruikmaakt van ASP.NET Core, is de standaardlimiet voor maximale diepte 32. De standaardwaarde is hetzelfde als voor modelbinding en wordt ingesteld in de JsonOptions-klasse.

JSON-tekenreeksen (eigenschapsnamen en tekenreekswaarden)

Tijdens de deserialisatie Newtonsoft.Json accepteert u eigenschapsnamen tussen dubbele aanhalingstekens, enkele aanhalingstekens of zonder aanhalingstekens. Hiermee worden tekenreekswaarden tussen dubbele aanhalingstekens of enkele aanhalingstekens geaccepteerd. Accepteert bijvoorbeeld Newtonsoft.Json de volgende JSON:

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

System.Text.Json accepteert alleen eigenschapsnamen en tekenreekswaarden tussen dubbele aanhalingstekens omdat deze indeling is vereist voor de RFC 8259-specificatie en is de enige indeling die als geldige JSON wordt beschouwd.

Een waarde tussen enkele aanhalingstekens resulteert in een JsonException met het volgende bericht:

''' is an invalid start of a value.

Niet-tekenreekswaarden voor tekenreekseigenschappen

Newtonsoft.Json accepteert niet-tekenreekswaarden, zoals een getal of de letterlijke waarden true en falsevoor deserialisatie op eigenschappen van het type tekenreeks. Hier volgt een voorbeeld van JSON dat Newtonsoft.Json deserializeert naar de volgende klasse:

{
  "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 deserialiseert niet niet-tekenreekswaarden in tekenreekseigenschappen. Een niet-tekenreekswaarde die is ontvangen voor een tekenreeksveld resulteert in een JsonException met het volgende bericht:

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

Scenario's met behulp van JsonSerializer

Sommige van de volgende scenario's worden niet ondersteund door ingebouwde functionaliteit, maar tijdelijke oplossingen zijn mogelijk. De tijdelijke oplossingen zijn aangepaste conversieprogramma's, die mogelijk geen volledige pariteit met Newtonsoft.Json functionaliteit bieden. Voor sommige hiervan wordt voorbeeldcode gegeven als voorbeelden. Als u van deze Newtonsoft.Json functies afhankelijk bent, zijn voor migratie wijzigingen in uw .NET-objectmodellen of andere codewijzigingen vereist.

In sommige van de volgende scenario's zijn tijdelijke oplossingen niet praktisch of mogelijk. Als u van deze Newtonsoft.Json functies afhankelijk bent, is migratie niet mogelijk zonder belangrijke wijzigingen.

Getallen tussen aanhalingstekens toestaan of schrijven

Newtonsoft.Json kan getallen serialiseren of deserialiseren die worden vertegenwoordigd door JSON-tekenreeksen (omgeven door aanhalingstekens). Het kan bijvoorbeeld accepteren: {"DegreesCelsius":"23"} in plaats van {"DegreesCelsius":23}. Als u dit gedrag wilt inschakelenSystem.Text.Json, instelt JsonSerializerOptions.NumberHandling op WriteAsString of AllowReadingFromStringgebruikt u het kenmerk [JsonNumberHandling].

Als u System.Text.Json indirect gebruikmaakt van ASP.NET Core, hoeft u niets te doen om gedrag te krijgen, zoals Newtonsoft.Json. ASP.NET Core geeft webstandaarden op wanneer deze wordt gebruikt System.Text.Json, en webstandaarden staan getallen tussen aanhalingsinstellingen toe.

Zie Getallen tussen aanhalingstekens toestaan of schrijven voor meer informatie.

Constructor opgeven die moet worden gebruikt bij het deserialiseren

Newtonsoft.Json[JsonConstructor] Met het kenmerk kunt u opgeven welke constructor moet worden aangeroepen bij het deserialiseren van een POCO.

System.Text.Json heeft ook een kenmerk [JsonConstructor]. . Zie Onveranderbare typen en records voor meer informatie.

Een eigenschap voorwaardelijk negeren

Newtonsoft.Json heeft verschillende manieren om een eigenschap voorwaardelijk te negeren bij serialisatie of deserialisatie:

  • DefaultContractResolver hiermee kunt u eigenschappen selecteren die u wilt opnemen of negeren, op basis van willekeurige criteria.
  • Met de NullValueHandling instellingen DefaultValueHandlingJsonSerializerSettings kunt u opgeven dat alle eigenschappen null-waarde of standaardwaarde moeten worden genegeerd.
  • Met de NullValueHandling en DefaultValueHandling instellingen op het [JsonProperty] kenmerk kunt u afzonderlijke eigenschappen opgeven die moeten worden genegeerd wanneer deze zijn ingesteld op null of de standaardwaarde.

System.Text.Json biedt de volgende manieren om eigenschappen of velden te negeren tijdens het serialiseren:

Bovendien kunt u in .NET 7 en latere versies het JSON-contract aanpassen om eigenschappen te negeren op basis van willekeurige criteria. Zie Aangepaste contracten voor meer informatie.

Met deze opties kunt u geselecteerde eigenschappen niet negeren op basis van willekeurige criteria die tijdens de runtime worden geëvalueerd.

Openbare en niet-openbare velden

Newtonsoft.Json kan velden en eigenschappen serialiseren en deserialiseren.

Gebruik System.Text.Jsonde JsonSerializerOptions.IncludeFields algemene instelling of het kenmerk [JsonInclude] om openbare velden op te nemen bij het serialiseren of deserialisatie. Zie Velden opnemen voor een voorbeeld.

Objectverwijzingen en handlelussen behouden

Newtonsoft.Json Serialiseert standaard op waarde. Als een object bijvoorbeeld twee eigenschappen bevat die een verwijzing naar hetzelfde Person object bevatten, worden de waarden van de eigenschappen van dat Person object gedupliceerd in de JSON.

Newtonsoft.Json heeft een PreserveReferencesHandling instelling JsonSerializerSettings waarmee u naslaginformatie kunt serialiseren:

  • Er wordt een id-metagegevens toegevoegd aan de JSON die voor het eerste Person object is gemaakt.
  • De JSON die voor het tweede Person object is gemaakt, bevat een verwijzing naar die id in plaats van eigenschapswaarden.

Newtonsoft.Json heeft ook een ReferenceLoopHandling instelling waarmee u kringverwijzingen kunt negeren in plaats van een uitzondering te genereren.

Als u verwijzingen wilt behouden en kringverwijzingen wilt System.Text.Jsonverwerken, stelt u deze in JsonSerializerOptions.ReferenceHandler op Preserve. De ReferenceHandler.Preserve instelling is gelijk aan PreserveReferencesHandling = PreserveReferencesHandling.All in Newtonsoft.Json.

De ReferenceHandler.IgnoreCycles optie heeft gedrag dat vergelijkbaar is met Newtonsoft.JsonReferenceLoopHandling.Ignore. Een verschil is dat de System.Text.Json implementatie referentielussen vervangt door het null JSON-token in plaats van de objectverwijzing te negeren. Zie Kringverwijzingen negeren voor meer informatie.

Net als de Newtonsoft.JsonReferenceResolver definieert de System.Text.Json.Serialization.ReferenceResolver klasse het gedrag van het behouden van verwijzingen op serialisatie en deserialisatie. Maak een afgeleide klasse om aangepast gedrag op te geven. Zie GuidReferenceResolver voor een voorbeeld.

Sommige gerelateerde Newtonsoft.Json functies worden niet ondersteund:

Zie Verwijzingen behouden en kringverwijzingen verwerken voor meer informatie.

Woordenlijst met niet-tekenreekssleutel

Zowel Newtonsoft.Json als System.Text.Json ondersteuning voor verzamelingen van het type Dictionary<TKey, TValue>. In System.Text.Json, TKey moet echter een primitief type zijn, niet een aangepast type. Zie Ondersteunde sleuteltypen voor meer informatie.

Let op

Deserialiseren naar een Dictionary<TKey, TValue> locatie die TKey wordt getypt als iets anders dan string een beveiligingsprobleem in de verbruikende toepassing kan veroorzaken. Zie dotnet/runtime#4761 voor meer informatie.

Typen zonder ingebouwde ondersteuning

System.Text.Json biedt geen ingebouwde ondersteuning voor de volgende typen:

Aangepaste conversieprogramma's kunnen worden geïmplementeerd voor typen die geen ingebouwde ondersteuning hebben.

Polymorfische serialisatie

Newtonsoft.Json voert automatisch polymorfe serialisatie uit. Vanaf .NET 7 ondersteunt System.Text.Json polymorfe serialisatie via het JsonDerivedTypeAttribute kenmerk. Zie Eigenschappen van afgeleide klassen serialiseren voor meer informatie.

Polymorfische deserialisatie

Newtonsoft.Json heeft een TypeNameHandling instelling waarmee metagegevens van het type worden toegevoegd aan de JSON tijdens het serialiseren. Hierbij worden de metagegevens gebruikt tijdens het deserialisatieen van polymorfe deserialisatie. Vanaf .NET 7 System.Text.Json is afhankelijk van typediscriminatiegegevens om polymorfische deserialisatie uit te voeren. Deze metagegevens worden verzonden in de JSON en vervolgens gebruikt tijdens deserialisatie om te bepalen of het basistype of een afgeleid type moet worden gedeserialiseerd. Zie Eigenschappen van afgeleide klassen serialiseren voor meer informatie.

Als u polymorfische deserialisatie in oudere .NET-versies wilt ondersteunen, maakt u een conversieprogramma zoals het voorbeeld in Aangepaste conversieprogramma's schrijven.

Tekenreekswaarden deserialiseren

System.Text.Json Standaard biedt dit geen ondersteuning voor deserialisatie van tekenreeksenumwaarden, terwijl Newtonsoft.Json dat wel het geval is. Met de volgende code wordt bijvoorbeeld een 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
}

U kunt echter deserialisatie van tekenreeksenumwaarden inschakelen met behulp van het JsonStringEnumConverter conversieprogramma. Zie Enums als tekenreeksen voor meer informatie.

Deserialisatie van objecteigenschappen

Wanneer Newtonsoft.Json dit wordt gedeserialiseerd, Objectis het:

  • Berekent het type primitieve waarden in de JSON-nettolading (anders dan null) en retourneert het opgeslagenstring, long, double, of booleanDateTime als een boxed object. Primitieve waarden zijn enkele JSON-waarden , zoals een JSON-getal, tekenreeks, true, falseof null.
  • Retourneert een JObject of JArray voor complexe waarden in de JSON-nettolading. Complexe waarden zijn verzamelingen van JSON-sleutel-waardeparen binnen accolades ({}) of lijsten met waarden tussen haakjes ([]). De eigenschappen en waarden binnen de accolades of vierkante haken kunnen aanvullende eigenschappen of waarden hebben.
  • Retourneert een null-verwijzing wanneer de nettolading de null letterlijke JSON-waarde heeft.

System.Text.Json slaat een vak op JsonElement voor primitieve en complexe waarden wanneer deserialisatie wordt uitgevoerd, Objectbijvoorbeeld:

  • Een object eigenschap.
  • Een object woordenlijstwaarde.
  • Een object matrixwaarde.
  • Een hoofdmap object.

System.Text.Json Behandelt echter hetzelfde als Newtonsoft.Json en retourneert null een null-verwijzing wanneer de nettolading de null letterlijke JSON-waarde bevat.

Als u typedeductie voor object eigenschappen wilt implementeren, maakt u een conversieprogramma zoals in het voorbeeld in Aangepaste conversieprogramma's schrijven.

Null deserialiseren naar niet-null-type

Newtonsoft.Json genereert geen uitzondering in het volgende scenario:

  • NullValueHandling is ingesteld op Ignore, en
  • Tijdens de deserialisatie bevat de JSON een null-waarde voor een niet-null-waardetype.

In hetzelfde scenario System.Text.Json wordt een uitzondering gegenereerd. (De bijbehorende instelling voor null-verwerking is System.Text.JsonJsonSerializerOptions.IgnoreNullValues = true.)

Als u eigenaar bent van het doeltype, is de beste tijdelijke oplossing om de eigenschap in kwestie nullable te maken (bijvoorbeeld wijzigen int in int?).

Een andere tijdelijke oplossing is om een conversieprogramma te maken voor het type, zoals het volgende voorbeeld waarmee null-waarden voor DateTimeOffset typen worden verwerkt:

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);
    }
}

Registreer dit aangepaste conversieprogramma met behulp van een kenmerk in de eigenschap of door het conversieprogramma toe te voegen aan de Converters verzameling.

Opmerking: het voorgaande conversieprogramma verwerkt null-waarden anders dan Newtonsoft.Json voor POCO's die standaardwaarden opgeven. Stel dat de volgende code uw doelobject vertegenwoordigt:

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; }
}

Stel dat de volgende JSON wordt gedeserialiseerd met behulp van het voorgaande conversieprogramma:

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

Na deserialisatie heeft de Date eigenschap 1/1/0001 (default(DateTimeOffset)dat wil gezegd, de waarde die is ingesteld in de constructor, wordt overschreven. Gezien dezelfde POCO en JSON zou Newtonsoft.Json deserialisatie 1-1-2001 in de Date accommodatie verlaten.

Deserialiseren naar onveranderbare klassen en structs

Newtonsoft.Json kan deserialiseren tot onveranderbare klassen en structs, omdat deze constructors met parameters kan gebruiken.

Gebruik System.Text.Jsonin het kenmerk [JsonConstructor] het gebruik van een geparameteriseerde constructor. Records in C# 9 zijn ook onveranderbaar en worden ondersteund als deserialisatiedoelen. Zie Onveranderbare typen en records voor meer informatie.

Vereiste eigenschappen

In Newtonsoft.Jsongeeft u op dat een eigenschap vereist is door het kenmerk in te [JsonProperty] stellenRequired. Newtonsoft.Json genereert een uitzondering als er geen waarde wordt ontvangen in de JSON voor een eigenschap die als vereist is gemarkeerd.

Vanaf .NET 7 kunt u de C# required -modifier of het JsonRequiredAttribute kenmerk voor een vereiste eigenschap gebruiken. System.Text.Json genereert een uitzondering als de JSON-nettolading geen waarde voor de gemarkeerde eigenschap bevat. Zie Vereiste eigenschappen voor meer informatie.

System.Text.Json genereert geen uitzondering als er geen waarde wordt ontvangen voor een van de eigenschappen van het doeltype. Als u bijvoorbeeld een WeatherForecast klasse hebt:

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

De volgende JSON wordt zonder fouten gedeserialiseerd:

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

Als u wilt dat deserialisatie mislukt als er geen Date eigenschap in de JSON staat, kiest u een van de volgende opties:

Met de volgende voorbeeldconversiecode wordt een uitzondering gegenereerd als de Date eigenschap niet is ingesteld nadat deserialisatie is voltooid:

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);
        }
    }
}

Registreer dit aangepaste conversieprogramma door het conversieprogramma toe te voegen aan de JsonSerializerOptions.Converters verzameling.

Dit patroon van recursief aanroepen van het conversieprogramma vereist dat u het conversieprogramma registreert met behulp JsonSerializerOptionsvan , niet met behulp van een kenmerk. Als u het conversieprogramma registreert met behulp van een kenmerk, roept het aangepaste conversieprogramma recursief aan bij zichzelf. Het resultaat is een oneindige lus die eindigt op een stack-overloopuitzondering.

Wanneer u het conversieprogramma registreert met behulp van het optiesobject, vermijdt u een oneindige lus door het optiesobject niet door te geven bij recursief aanroepen Serialize of Deserialize. Het optiesobject bevat de Converters verzameling. Als u deze doorgeeft aan Serialize of Deserialize, roept het aangepaste conversieprogramma zichzelf aan, waardoor een oneindige lus wordt gemaakt die resulteert in een stack-overloop-uitzondering. Als de standaardopties niet haalbaar zijn, maakt u een nieuw exemplaar van de opties met de instellingen die u nodig hebt. Deze benadering is traag omdat elke nieuwe instantie onafhankelijk van elkaar in de cache wordt opgeslagen.

Er is een alternatief patroon dat registratie op de klasse kan gebruiken JsonConverterAttribute om te worden geconverteerd. In deze benadering roept Serialize de conversiecode aan of Deserialize op een klasse die is afgeleid van de klasse die moet worden geconverteerd. De afgeleide klasse heeft er geen JsonConverterAttribute toepassing op. In het volgende voorbeeld van dit alternatief:

  • WeatherForecastWithRequiredPropertyConverterAttribute is de klasse die moet worden gedeserialiseerd en waarop de JsonConverterAttribute klasse moet worden toegepast.
  • WeatherForecastWithoutRequiredPropertyConverterAttribute is de afgeleide klasse die het conversiekenmerk niet heeft.
  • De code in de conversieprogrammaaanroepen Serialize en Deserialize aan om WeatherForecastWithoutRequiredPropertyConverterAttribute een oneindige lus te voorkomen. Er zijn prestatiekosten voor deze benadering voor serialisatie vanwege een extra object-instantiering en het kopiëren van eigenschapswaarden.

Dit zijn de WeatherForecast* typen:

[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
{
}

En hier is het conversieprogramma:

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);
        }
    }
}

Het vereiste conversieprogramma voor eigenschappen vereist extra logica als u kenmerken zoals [JsonIgnore] of andere opties, zoals aangepaste coderingsprogramma's, moet afhandelen. De voorbeeldcode verwerkt ook geen eigenschappen waarvoor een standaardwaarde is ingesteld in de constructor. En deze benadering maakt geen onderscheid tussen de volgende scenario's:

  • Er ontbreekt een eigenschap in de JSON.
  • Een eigenschap voor een niet-null-type is aanwezig in de JSON, maar de waarde is de standaardwaarde voor het type, zoals nul voor een int.
  • Een eigenschap voor een type null-waarde is aanwezig in de JSON, maar de waarde is null.

Notitie

Als u System.Text.Json gebruikmaakt van een ASP.NET Core-controller, kunt u mogelijk een [Required] kenmerk gebruiken voor eigenschappen van de modelklasse in plaats van een System.Text.Json conversieprogramma te implementeren.

Datumnotatie opgeven

Newtonsoft.Json biedt verschillende manieren om te bepalen hoe eigenschappen van DateTime en DateTimeOffset typen worden geserialiseerd en gedeserialiseerd:

  • De DateTimeZoneHandling instelling kan worden gebruikt om alle DateTime waarden te serialiseren als UTC-datums.
  • De DateFormatString instelling en DateTime conversieprogramma's kunnen worden gebruikt om de notatie van datumtekenreeksen aan te passen.

System.Text.Json ondersteunt ISO 8601-1:2019, inclusief het RFC 3339-profiel. Deze indeling wordt algemeen aangenomen, ondubbelzinnig en maakt rondreizen precies. Als u een andere indeling wilt gebruiken, maakt u een aangepast conversieprogramma. De volgende conversieprogramma's serialiseren en deserialiseren JSON die een Unix-epoch-indeling gebruikt met of zonder een tijdzoneverschil (waarden zoals /Date(1590863400000-0700)/ of /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);
    }
}

Zie de ondersteuning voor DateTime en DateTimeOffset in System.Text.Jsonvoor meer informatie.

Callbacks

Newtonsoft.Json hiermee kunt u aangepaste code uitvoeren op verschillende punten in het serialisatie- of deserialisatieproces:

  • OnDeserialiseren (wanneer een object begint te deserialiseren)
  • OnDeserialized (wanneer u klaar bent met het deserialiseren van een object)
  • OnSerialiseren (wanneer een object wordt geserialiseerd)
  • OnSerialized (wanneer u klaar bent met het serialiseren van een object)

System.Text.Json geeft dezelfde meldingen weer tijdens serialisatie en deserialisatie. Als u deze wilt gebruiken, implementeert u een of meer van de volgende interfaces uit de System.Text.Json.Serialization naamruimte:

Hier volgt een voorbeeld dat controleert op een null-eigenschap en berichten schrijft aan het begin en einde van serialisatie en deserialisatie:

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=

De OnDeserializing code heeft geen toegang tot het nieuwe POCO-exemplaar. Als u het nieuwe POCO-exemplaar aan het begin van deserialisatie wilt bewerken, plaatst u die code in de POCO-constructor.

Niet-openbare eigenschappensetters en getters

Newtonsoft.Json kan persoonlijke en interne eigenschapssetters en getters gebruiken via het JsonProperty kenmerk.

System.Text.Jsonondersteunt persoonlijke en interne eigenschapssetters en getters via het kenmerk [JsonInclude]. Zie Niet-openbare eigenschapstoegangsors voor voorbeeldcode.

Bestaande objecten vullen

Met de JsonConvert.PopulateObject methode in Newtonsoft.Json deserialisatie wordt een JSON-document gedeserialiseerd naar een bestaand exemplaar van een klasse, in plaats van een nieuw exemplaar te maken. System.Text.Json maakt altijd een nieuw exemplaar van het doeltype met behulp van de standaard openbare parameterloze constructor. Aangepaste conversieprogramma's kunnen deserialiseren naar een bestaand exemplaar.

Eigenschappen opnieuw gebruiken in plaats van eigenschappen te vervangen

Vanaf .NET 8 ondersteunt System.Text.Json het hergebruik van geïnitialiseerde eigenschappen in plaats van ze te vervangen. Er zijn enkele verschillen in gedrag, waarover u kunt lezen in het API-voorstel.

Zie Geïnitialiseerde eigenschappen vullen voor meer informatie.

Met de ObjectCreationHandling instelling kunt Newtonsoft.Json u opgeven dat objecten in eigenschappen opnieuw moeten worden gebruikt in plaats van te worden vervangen tijdens de deserialisatie. System.Text.Json vervangt altijd objecten in eigenschappen. Aangepaste conversieprogramma's kunnen deze functionaliteit bieden of u kunt een upgrade uitvoeren naar .NET 8, waarmee u de functionaliteit kunt vullen.

Eigenschappen zonder setters vullen

Vanaf .NET 8 worden invullende eigenschappen ondersteund System.Text.Json , inclusief eigenschappen die geen setter hebben. Zie Geïnitialiseerde eigenschappen vullen voor meer informatie.

Tijdens de deserialisatie voegt u objecten toe aan een verzameling, Newtonsoft.Json zelfs als de eigenschap geen setter heeft. System.Text.Json negeert eigenschappen die geen setters hebben. Aangepaste conversieprogramma's kunnen deze functionaliteit bieden of u kunt upgraden naar .NET 8, waarmee alleen-lezeneigenschappen kunnen worden gevuld.

Naamgevingsbeleid voor slangencases

System.Text.Json bevat een ingebouwd naamgevingsbeleid voor snake case. Er zijn echter enkele gedragsverschillen met Newtonsoft.Json voor sommige invoer. In de volgende tabel ziet u enkele van deze verschillen bij het converteren van invoer met behulp van het JsonNamingPolicy.SnakeCaseLower beleid.

Invoer Newtonsoft.Json Resultaat System.Text.Json Resultaat
"AB1" "a_b1" "ab1"
"SHA512Managed" "sh_a512_managed" "sha512_managed"
"abc123DEF456" "abc123_de_f456" "abc123_def456"
"USE-CASE" "keba_b-_case" "kebab-case"

Het enige ingebouwde naamgevingsbeleid System.Text.Json voor eigenschappen is voor kameel geval. Newtonsoft.Json kan eigenschapsnamen converteren naar slangenkoffer. Een aangepast naamgevingsbeleid kan deze functionaliteit bieden of een upgrade uitvoeren naar .NET 8 of hoger, inclusief ingebouwd naamgevingsbeleid voor slangencases.

System.Runtime.Serialization-kenmerken

System.Runtime.Serialization kenmerken zoals DataContractAttribute, DataMemberAttributeen IgnoreDataMemberAttribute u kunt een gegevenscontract definiëren. Een gegevenscontract is een formele overeenkomst tussen een service en een klant die de gegevens die moeten worden uitgewisseld abstract beschrijft. Het gegevenscontract definieert nauwkeurig welke eigenschappen worden geserialiseerd voor uitwisseling.

System.Text.Json biedt geen ingebouwde ondersteuning voor deze kenmerken. Vanaf .NET 7 kunt u echter een aangepaste type resolver gebruiken om ondersteuning toe te voegen. Zie ZCS voor een voorbeeld. DataContractResolver.

Octale getallen

Newtonsoft.Json behandelt getallen met een voorloopnul als octale getallen. System.Text.Json staat geen voorloopnullen toe omdat de RFC 8259-specificatie ze niet toestaat.

Ontbrekende leden verwerken

Als de JSON die wordt gedeserialiseerd eigenschappen bevat die ontbreken in het doeltype, Newtonsoft.Json kan worden geconfigureerd om uitzonderingen te genereren. System.Text.Json Standaard worden extra eigenschappen in de JSON genegeerd, behalve wanneer u het kenmerk [JsonExtensionData] gebruikt.

In .NET 8 en latere versies kunt u uw voorkeur instellen voor het overslaan of weigeren van niet-toegewezen JSON-eigenschappen met een van de volgende methoden:

JsonObjectAttribute

Newtonsoft.Json heeft een kenmerk, JsonObjectAttributedat kan worden toegepast op het typeniveau om te bepalen welke leden worden geserialiseerd, hoe null waarden worden verwerkt en of alle leden vereist zijn. System.Text.Json heeft geen equivalent kenmerk dat kan worden toegepast op een type. Voor sommige gedragingen, zoals null het verwerken van waarden, kunt u hetzelfde gedrag voor de globale JsonSerializerOptions of afzonderlijke eigenschappen configureren.

Bekijk het volgende voorbeeld dat wordt gebruikt Newtonsoft.Json.JsonObjectAttribute om op te geven dat alle null eigenschappen moeten worden genegeerd:

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

In System.Text.Jsonkunt u het gedrag voor alle typen en eigenschappen instellen:

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

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

U kunt ook het gedrag voor elke eigenschap afzonderlijk instellen:

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

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

Bekijk vervolgens het volgende voorbeeld dat wordt gebruikt Newtonsoft.Json.JsonObjectAttribute om op te geven dat alle lideigenschappen aanwezig moeten zijn in de JSON:

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

U kunt hetzelfde gedrag bereiken System.Text.Json door de C# required -modifier of de JsonRequiredAttributeaan elke eigenschap toe te voegen. Zie Vereiste eigenschappen voor meer informatie.

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

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

TraceWriter

Newtonsoft.Json hiermee kunt u fouten opsporen met behulp van een TraceWriter logboeken die worden gegenereerd door serialisatie of deserialisatie. System.Text.Json maakt geen logboekregistratie.

JsonDocument en JsonElement vergeleken met JToken (zoals JObject, JArray)

System.Text.Json.JsonDocument biedt de mogelijkheid om een alleen-lezen Document Object Model (DOM) te parseren en bouwen op basis van bestaande JSON-nettoladingen. De DOM biedt willekeurige toegang tot gegevens in een JSON-nettolading. De JSON-elementen die de nettolading vormen, kunnen worden geopend via het JsonElement type. Het JsonElement type biedt API's voor het converteren van JSON-tekst naar algemene .NET-typen. JsonDocument maakt een RootElement eigenschap beschikbaar.

Vanaf .NET 6 kunt u een veranderlijke DOM parseren en bouwen op basis van bestaande JSON-nettoladingen met behulp van het JsonNode type en andere typen in de System.Text.Json.Nodes naamruimte. Zie Use JsonNodevoor meer informatie.

JsonDocument is IDisposable

JsonDocument bouwt een in-memory weergave van de gegevens in een poolbuffer. Daarom, in tegenstelling tot JObject of JArray van Newtonsoft.Json, het JsonDocument type IDisposable implementeert en moet worden gebruikt binnen een gebruiksblok. Zie JsonDocument is IDisposable voor meer informatie.

JsonDocument heeft het kenmerk Alleen-lezen

De System.Text.Json DOM kan geen JSON-elementen toevoegen, verwijderen of wijzigen. Het is ontworpen op deze manier voor prestaties en om toewijzingen te verminderen voor het parseren van algemene JSON-nettoladinggrootten (dat < wil gezegd 1 MB).

JsonElement is een samenvoegstruct

JsonDocument geeft de RootElement eigenschap als een eigenschap van het type JsonElementweer, een samenvoegingsstructtype dat elk JSON-element omvat. Newtonsoft.Jsonmaakt gebruik van toegewezen hiërarchische typen, JTokenzoals JObject,JArray enzovoort. JsonElement is wat u kunt doorzoeken en opsommen en kunt u gebruiken JsonElement om JSON-elementen te materialiseren in .NET-typen.

Vanaf .NET 6 kunt u typen en typen gebruiken JsonNode in de System.Text.Json.Nodes naamruimte die overeenkomen met JObject,JArray en JToken. Zie Use JsonNodevoor meer informatie.

Een JsonDocument en JsonElement doorzoeken op subelementen

Hiermee wordt gezocht naar JSON-tokens die vaak relatief snel worden gebruikt JObject , JArrayNewtonsoft.Json omdat ze zoekacties zijn in een bepaalde woordenlijst. Ter vergelijking: zoekopdrachten JsonElement vereisen een sequentiële zoekopdracht van de eigenschappen en zijn daarom relatief traag (bijvoorbeeld bij gebruik TryGetProperty). System.Text.Json is ontworpen om de initiële parseringstijd te minimaliseren in plaats van opzoektijd. Zie Een JsonDocument en JsonElement doorzoeken voor subelementen voor meer informatie.

Utf8JsonReader versus JsonTextReader

System.Text.Json.Utf8JsonReaderis een high-performance, lage toewijzing, alleen-doorstuurlezer voor UTF-8 gecodeerde JSON-tekst, gelezen uit een ReadOnlySpan<byte> of ReadOnlySequence<byte>. Het Utf8JsonReader is een type op laag niveau dat kan worden gebruikt om aangepaste parsers en ontserialisaties te bouwen.

Utf8JsonReader is een ref-struct

De JsonTextReader in Newtonsoft.Json is een klas. Het Utf8JsonReader type verschilt in dat het een verw-struct is. Zie verw-structbeperkingen voor Utf8JsonReader voor meer informatie.

Null-waarden lezen in typen null-waarden

Newtonsoft.Json biedt API's die Nullable<T>retourneren, zoals ReadAsBoolean, die een NullTokenType voor u verwerken door een bool?. De ingebouwde System.Text.Json API's retourneren alleen niet-null-waardetypen. Zie Null-waarden lezen in typen null-waarden voor meer informatie.

Meerdere doelen voor het lezen van JSON

Als u wilt blijven gebruiken Newtonsoft.Json voor bepaalde doelframeworks, kunt u meerdere doelen hebben en twee implementaties hebben. Dit is echter niet triviaal en zou enige #ifdefs en bronduplicatie vereisen. Een manier om zoveel mogelijk code te delen, is door een ref struct wrapper rond Utf8JsonReader en Newtonsoft.Json.JsonTextReader. Deze wrapper zou het openbare oppervlak samenvoegen terwijl de gedragsverschillen worden geïsoleerd. Hiermee kunt u de wijzigingen voornamelijk isoleren in de constructie van het type, samen met het doorgeven van het nieuwe type per verwijzing. Dit is het patroon dat de bibliotheek Microsoft.Extensions.DependencyModel volgt:

Utf8JsonWriter versus JsonTextWriter

System.Text.Json.Utf8JsonWriter is een krachtige manier om UTF-8 gecodeerde JSON-tekst te schrijven van veelgebruikte .NET-typen, zoals String, Int32en DateTime. De schrijver is een type op laag niveau dat kan worden gebruikt voor het bouwen van aangepaste serializers.

Onbewerkte waarden schrijven

Newtonsoft.Json heeft een WriteRawValue methode waarmee onbewerkte JSON wordt geschreven waar een waarde wordt verwacht. System.Text.Json heeft een direct equivalent: Utf8JsonWriter.WriteRawValue. Zie Onbewerkte JSON schrijven voor meer informatie.

JSON-indeling aanpassen

JsonTextWriter bevat de volgende instellingen, waarvoor Utf8JsonWriter geen equivalent is:

  • QuoteChar : hiermee geeft u het teken op dat moet worden gebruikt om tekenreekswaarden te plaatsen. Utf8JsonWriter gebruikt altijd dubbele aanhalingstekens.
  • QuoteName - Hiermee geeft u op of eigenschapsnamen wel of niet tussen aanhalingstekens moeten worden geplaatst. Utf8JsonWriter plaatst ze altijd tussen aanhalingstekens.

Vanaf .NET 9 kunt u het inspringingsteken en de grootte aanpassen voor Utf8JsonWriter het gebruik van opties die door de JsonWriterOptions struct worden weergegeven:

  • JsonWriterOptions.IndentCharacter
  • JsonWriterOptions.IndentSize

JsonTextWriter bevat de volgende instellingen, waarvoor Utf8JsonWriter geen equivalent is:

  • Inspringing : hiermee geeft u op hoeveel tekens u wilt laten inspringen. Utf8JsonWriter wordt altijd met 2 tekens ingesprongen.
  • IndentChar : hiermee geeft u het teken op dat moet worden gebruikt voor inspringing. Utf8JsonWriter maakt altijd gebruik van witruimte.
  • QuoteChar : hiermee geeft u het teken op dat moet worden gebruikt om tekenreekswaarden te plaatsen. Utf8JsonWriter gebruikt altijd dubbele aanhalingstekens.
  • QuoteName - Hiermee geeft u op of eigenschapsnamen wel of niet tussen aanhalingstekens moeten worden geplaatst. Utf8JsonWriter plaatst ze altijd tussen aanhalingstekens.

Er zijn geen tijdelijke oplossingen waarmee u de JSON Utf8JsonWriter op deze manieren kunt aanpassen.

Tijdspanne, URI- of tekenwaarden schrijven

JsonTextWriter biedt WriteValue methoden voor tijdspan-, URI- en tekenwaarden . Utf8JsonWriter heeft geen equivalente methoden. Maak deze waarden in plaats daarvan op als tekenreeksen (bijvoorbeeld door aan te roepen ToString()) en aan te roepen WriteStringValue.

Meerdere doelen voor het schrijven van JSON

Als u wilt blijven gebruiken Newtonsoft.Json voor bepaalde doelframeworks, kunt u meerdere doelen hebben en twee implementaties hebben. Dit is echter niet triviaal en zou enige #ifdefs en bronduplicatie vereisen. Een manier om zoveel mogelijk code te delen, is door een wrapper rond Utf8JsonWriter en Newtonsoft.Json.JsonTextWriter. Deze wrapper zou het openbare oppervlak samenvoegen terwijl de gedragsverschillen worden geïsoleerd. Hiermee kunt u de wijzigingen voornamelijk isoleren in de constructie van het type. De bibliotheek Microsoft.Extensions.DependencyModel volgt:

TypeNameHandling.All wordt niet ondersteund

De beslissing om equivalente functionaliteit uit System.Text.Json te sluitenTypeNameHandling.All, was opzettelijk. Het toestaan van een JSON-nettolading om zijn eigen typegegevens op te geven, is een veelvoorkomende bron van beveiligingsproblemen in webtoepassingen. Met name door deze Newtonsoft.JsonTypeNameHandling.All configuratie kan de externe client een volledige uitvoerbare toepassing insluiten binnen de JSON-nettolading zelf, zodat tijdens de deserialisatie de webtoepassing wordt geëxtraheerd en de ingesloten code wordt uitgevoerd. Zie vrijdag de 13e JSON-aanvallen van PowerPoint en vrijdag de details van de 13e JSON-aanvallen voor meer informatie.

JSON-padquery's worden niet ondersteund

De JsonDocument DOM biedt geen ondersteuning voor het uitvoeren van query's met behulp van JSON-pad.

In een JsonNode DOM heeft elk JsonNode exemplaar een GetPath methode die een pad naar dat knooppunt retourneert. Er is echter geen ingebouwde API voor het afhandelen van query's op basis van JSON Path-queryreeksen.

Zie het probleem met dotnet/runtime #31068 GitHub voor meer informatie.

Sommige limieten kunnen niet worden geconfigureerd

System.Text.Json stelt limieten in die niet kunnen worden gewijzigd voor sommige waarden, zoals de maximale tokengrootte in tekens (166 MB) en in basis 64 (125 MB). Zie JsonConstants voor meer informatie de broncode en GitHub probleem dotnet/runtime #39953.

NaN, Infinity, -Infinity

Newtonsoft parseert NaNtokens en Infinity-Infinity JSON-tekenreeksen. Met System.Text.Json, gebruik JsonNumberHandling.AllowNamedFloatingPointLiterals. Zie Getallen tussen aanhalingstekens toestaan of schrijven voor informatie over het gebruik van deze instelling.

Aanvullende bronnen