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.6.2 en latere versies
- .NET Core 2.0, 2.1 en 2.2
Tip
U kunt AI-hulp gebruiken om te migreren met Newtonsoft.Json
GitHub Copilot.
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.
Het System.Text.Json
team investeert 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 dezeNewtonsoft.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 equivalent |
---|---|
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 equivalent |
---|---|
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 equivalent |
---|---|
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:
- Kenmerk op eigenschap
- Kenmerk op type
- Conversieprogramma's verzamelen
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.
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 false
voor 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
instellingenDefaultValueHandling
JsonSerializerSettings
kunt u opgeven dat alle eigenschappen null-waarde of standaardwaarde moeten worden genegeerd. - Met de
NullValueHandling
enDefaultValueHandling
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:
- Het kenmerk [JsonIgnore] voor een eigenschap zorgt ervoor dat de eigenschap tijdens de serialisatie wordt weggelaten uit de JSON.
- Met de algemene optie IgnoreReadOnlyProperties kunt u alle alleen-lezeneigenschappen negeren.
- Als u velden opgeeft, kunt u met de JsonSerializerOptions.IgnoreReadOnlyFields algemene optie alle alleen-lezen velden negeren.
- Met de
DefaultIgnoreCondition
algemene optie kunt u alle eigenschappen van het waardetype met standaardwaarden negeren of alle eigenschappen van het verwijzingstype negeren die null-waarden hebben.
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:
- DataTable en gerelateerde typen (zie Ondersteunde verzamelingstypen) voor meer informatie
- ExpandoObject
- TimeZoneInfo
- BigInteger
- DBNull
- Type
- ValueTuple en de bijbehorende algemene 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
, ofboolean
DateTime
als een boxed object. Primitieve waarden zijn enkele JSON-waarden , zoals een JSON-getal, tekenreeks,true
,false
ofnull
. - Retourneert een
JObject
ofJArray
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 opIgnore
, 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.Json
JsonSerializerOptions.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.Json
geeft 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:
- Gebruik de .NET 7 of nieuwere versie van het System.Text.Json pakket en voeg de
required
modifier (beschikbaar vanaf C# 11) of het JsonRequiredAttribute kenmerk toe aan de eigenschap. - Een aangepast conversieprogramma implementeren.
OnDeserialized
Een callback (.NET 6 en hoger) implementeren.
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 deJsonConverterAttribute
klasse moet worden toegepast.WeatherForecastWithoutRequiredPropertyConverterAttribute
is de afgeleide klasse die het conversiekenmerk niet heeft.- De code in de conversieprogrammaaanroepen
Serialize
enDeserialize
aan omWeatherForecastWithoutRequiredPropertyConverterAttribute
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 alleDateTime
waarden te serialiseren als UTC-datums. - De
DateFormatString
instelling enDateTime
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:
- Pas het JsonUnmappedMemberHandlingAttribute kenmerk toe op het type waarop u deserialiseert.
- Als u uw voorkeur globaal wilt instellen, stelt u de JsonSerializerOptions.UnmappedMemberHandling eigenschap in. Of stel voor het genereren van de bron de JsonSourceGenerationOptionsAttribute.UnmappedMemberHandling eigenschap in en pas het kenmerk toe op uw JsonSerializerContext klasse.
- Pas de JsonTypeInfo.UnmappedMemberHandling eigenschap aan.
JsonObjectAttribute
Newtonsoft.Json
heeft een kenmerk, JsonObjectAttribute
dat 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 JsonRequiredAttribute aan 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 JsonNode
voor 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.Json
maakt gebruik van toegewezen hiërarchische typen, zoals JObject
, JArray
, JToken
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 overeenkomt met JObject
, JArray
en JToken
. Zie Use JsonNode
voor meer informatie.
Een JsonDocument en JsonElement doorzoeken op subelementen
Hiermee wordt gezocht naar JSON-tokens die vaak relatief snel worden gebruikt JObject
, JArray
Newtonsoft.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 Null
TokenType
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
, Int32
en 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:
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.Json
TypeNameHandling.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 NaN
tokens 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.
GitHub Copilot gebruiken om te migreren
U kunt hulp krijgen bij het coderen van GitHub Copilot om uw code in uw IDE te converteren.
Als u Visual Studio 2022 versie 17.8 of hoger gebruikt, kunt u de AI-gestuurde GitHub Copilot in Visual Studio proberen om uw Newtonsoft.Json
code te migreren voor gebruikSystem.Text.Json
. Verzend uw vraag en de code die u wilt converteren als een prompt in het copilot-chatvenster, zoals in het volgende voorbeeld.
Notitie
GitHub Copilot wordt mogelijk gemaakt door AI, dus verrassingen en fouten zijn mogelijk. Zorg ervoor dat u alle gegenereerde code of suggesties controleert. Zie de veelgestelde vragen over GitHub Copilot voor meer informatie over het algemene gebruik van GitHub Copilot, productimpact, menselijk toezicht en privacy.
Voorbeeldprompt voor Copilot Chat
convert the following code to use System.Text.Json
Product product = new Product();
product.Name = "Apple";
product.ExpiryDate = new DateTime(2024, 08, 08);
product.Price = 3.99M;
product.Sizes = new string[] { "Small", "Medium", "Large" };
string output = JsonConvert.SerializeObject(product);
Console.WriteLine(output);
Voorbeeld van Copilot Chat-antwoord
To convert the code to use System.Text.Json, you can use the JsonSerializer class. Here's the updated code:
using System;
using System.Text.Json;
public class Product
{
public string Name { get; set; }
public DateTime ExpiryDate { get; set; }
public decimal Price { get; set; }
public string[] Sizes { get; set; }
}
public class Program
{
public static void Main()
{
Product product = new Product();
product.Name = "Apple";
product.ExpiryDate = new DateTime(2024, 08, 08);
product.Price = 3.99M;
product.Sizes = new string[] { "Small", "Medium", "Large" };
string output = JsonSerializer.Serialize(product);
Console.WriteLine(output);
}
}
This code uses System.Text.Json.JsonSerializer.Serialize to convert the Product object to a JSON string.
Houd er rekening mee dat uw resultaten mogelijk afwijken van wat in deze voorbeeldantwoorden wordt weergegeven. AI-modellen zijn niet-deterministisch, wat betekent dat ze verschillende antwoorden kunnen retourneren wanneer ze dezelfde vraag stellen. Dit kan worden veroorzaakt door extra leer- en aanpassing in de loop van de tijd, taalvariatie, wijzigingen in context, zoals uw chatgeschiedenis en meer.
U kunt chatfuncties, zoals slash-opdrachten, verwijzingen en threads, gebruiken om intenties in te stellen en betere antwoorden te krijgen met contextbereik.
Als uw codebestand filename
bijvoorbeeld is geopend in de IDE, kunt u verwijzen naar het bestand in uw prompt naar Copilot Chat met 'converteren #filename
om te gebruiken System.Text.Json
'. U kunt ook verwijzen naar de oplossing met 'converteren @workspace
om te gebruiken System.Text.Json
' in het chatvenster of inlinechat.