Null-aantekeningen respecteren
Vanaf .NET 9 JsonSerializer heeft (beperkte) ondersteuning voor niet-nullable verwijzingstypen afdwingen in zowel serialisatie als deserialisatie. U kunt deze ondersteuning in-/uitschakelen met behulp van de JsonSerializerOptions.RespectNullableAnnotations vlag.
Het volgende codefragment genereert bijvoorbeeld een JsonException tijdens serialisatie met een bericht als volgt:
De eigenschap of het veld 'Naam' voor het type 'Persoon' staat het ophalen van null-waarden niet toe. Overweeg de aantekening van de null-waarde bij te werken.
public static void RunIt()
{
#nullable enable
JsonSerializerOptions options = new()
{
RespectNullableAnnotations = true
};
Person invalidValue = new(Name: null!);
JsonSerializer.Serialize(invalidValue, options);
}
record Person(string Name);
Op dezelfde manier RespectNullableAnnotations wordt null-baarheid afgedwongen bij deserialisatie. Het volgende codefragment genereert een JsonException tijdens serialisatie met een bericht zoals:
De constructorparameter 'Naam' voor het type 'Persoon' staat geen null-waarden toe. Overweeg de aantekening van de null-waarde bij te werken.
public static void RunIt()
{
#nullable enable
JsonSerializerOptions options = new()
{
RespectNullableAnnotations = true
};
string json = """{"Name":null}""";
JsonSerializer.Deserialize<Person>(json, options);
}
record Person(string Name);
Tip
- U kunt null-functionaliteit op afzonderlijk eigenschapsniveau configureren met behulp van de IsGetNullable en IsSetNullable eigenschappen.
- De C#-compiler gebruikt de
[NotNull]
kenmerken ,[AllowNull]
en[DisallowNull]
[MaybeNull]
kenmerken om aantekeningen in getters en setters nauwkeurig af te stemmen. Deze kenmerken worden ook herkend door deze System.Text.Json functie. (Zie voor meer informatie over de kenmerken Kenmerken voor statische analyse met null-status.)
Beperkingen
Vanwege de implementatie van niet-null-referentietypen heeft deze functie enkele belangrijke beperkingen. Raak vertrouwd met deze beperkingen voordat u de functie inschakelt. De hoofdmap van het probleem is dat verwijzingstype nullability geen eersteklas representatie heeft in de tussenliggende taal (IL). Als zodanig zijn de expressies MyPoco
en MyPoco?
zijn ze niet te onderscheiden vanuit het perspectief van runtime-reflectie. Hoewel de compiler ervoor probeert te zorgen door kenmerkmetagegevens te verzenden (zie sharplab.io voorbeeld), zijn deze metagegevens beperkt tot niet-algemene lidaantekeningen die zijn gericht op een bepaalde typedefinitie. Deze beperking is de reden dat de vlag alleen null-annotaties valideert die aanwezig zijn op niet-algemene eigenschappen, velden en constructorparameters. System.Text.Json biedt geen ondersteuning voor afdwinging van null-waarden voor:
- Typen op het hoogste niveau of het type dat wordt doorgegeven bij het maken van de eerste
JsonSerializer.Deserialize()
ofJsonSerializer.Serialize()
aanroep. - Typen verzamelingselementen, bijvoorbeeld de
List<string>
typen enList<string?>
typen zijn niet te onderscheiden. - Eigenschappen, velden of constructorparameters die algemeen zijn.
Als u in deze gevallen null-afdwinging wilt toevoegen, modelleert u uw type als een struct (omdat ze geen null-waarden toelaten) of maakt u een aangepast conversieprogramma dat de eigenschap overschrijft HandleNull aan true
.
Functieschakelaar
U kunt de RespectNullableAnnotations
instelling globaal inschakelen met behulp van de System.Text.Json.Serialization.RespectNullableAnnotationsDefault
functieschakelaar. Voeg het volgende MSBuild-item toe aan uw projectbestand (bijvoorbeeld .csproj-bestand ):
<ItemGroup>
<RuntimeHostConfigurationOption Include="System.Text.Json.Serialization.RespectNullableAnnotationsDefault" Value="true" />
</ItemGroup>
De RespectNullableAnnotationsDefault
API is geïmplementeerd als een opt-in-vlag in .NET 9 om te voorkomen dat bestaande toepassingen worden onderbroken. Als u een nieuwe toepassing schrijft, is het raadzaam deze vlag in te schakelen in uw code.
Relatie tussen nullable en optionele parameters
RespectNullableAnnotations breidt afdwinging niet uit naar niet-opgegeven JSON-waarden, omdat System.Text.Json vereiste en niet-nullbare eigenschappen worden behandeld als orthogonale concepten. Het volgende codefragment genereert bijvoorbeeld geen uitzondering tijdens deserialisatie:
public static void RunIt()
{
JsonSerializerOptions options = new()
{
RespectNullableAnnotations = true
};
var result = JsonSerializer.Deserialize<MyPoco>("{}", options);
Console.WriteLine(result.Name is null); // True.
}
class MyPoco
{
public string Name { get; set; }
}
Dit gedrag komt voort uit de C#-taal zelf, waar u vereiste eigenschappen kunt hebben die nullable zijn:
MyPoco poco = new() { Value = null }; // No compiler warnings.
class MyPoco
{
public required string? Value { get; set; }
}
En u kunt ook optionele eigenschappen hebben die niet nullable zijn:
class MyPoco
{
public string Value { get; set; } = "default";
}
Dezelfde orthogonaliteit is van toepassing op constructorparameters:
record MyPoco(
string RequiredNonNullable,
string? RequiredNullable,
string OptionalNonNullable = "default",
string? OptionalNullable = "default"
);