Migrace z Newtonsoft.Json do System.Text.Json
Tento článek ukazuje, jak migrovat z Newtonsoft.Json do System.Text.Json.
Obor System.Text.Json
názvů poskytuje funkce pro serializaci do a deserializaci z JavaScript Object Notation (JSON). Knihovna System.Text.Json
je součástí modulu runtime pro .NET Core 3.1 a novější verze. V případě jiných cílových architektur nainstalujte System.Text.Json balíček NuGet. Balíček podporuje:
- .NET Standard 2.0 a novější verze
- .NET Framework 4.6.2 a novější verze
- .NET Core 2.0, 2.1 a 2.2
Tip
Pomoc s AI můžete použít k migraci z Newtonsoft.Json
GitHub Copilotu.
System.Text.Json
zaměřuje se především na dodržování předpisů v oblasti výkonu, zabezpečení a standardů. Má několik klíčových rozdílů ve výchozím chování a nemá za cíl mít paritu funkcí s Newtonsoft.Json
. V některých scénářích System.Text.Json
aktuálně nemá žádné integrované funkce, ale existují doporučená alternativní řešení. V jiných scénářích jsou alternativní řešení nepraktická.
Tým System.Text.Json
investuje do přidávání funkcí, které jsou nejčastěji požadovány. Pokud vaše aplikace závisí na chybějící funkci, zvažte vytvoření problému v úložišti GitHubu dotnet/runtime a zjistěte, jestli je možné přidat podporu pro váš scénář.
Většina tohoto článku se zabývá tím, jak používat JsonSerializer rozhraní API, ale obsahuje také pokyny k použití JsonDocument (které představuje objektový model dokumentu nebo MODEL DOM) Utf8JsonReadera Utf8JsonWriter typy.
V jazyce Visual Basic nemůžete použít Utf8JsonReader, což také znamená, že nemůžete psát vlastní převaděče. Většina zde uvedených alternativních řešení vyžaduje, abyste napsali vlastní převaděče. Vlastní převaděč můžete napsat v jazyce C# a zaregistrovat ho v projektu jazyka Visual Basic. Další informace naleznete v tématu Podpora jazyka Visual Basic.
Tabulka rozdílů
Následující tabulka uvádí Newtonsoft.Json
funkce a System.Text.Json
ekvivalenty. Ekvivalenty spadají do následujících kategorií:
- ✔️ Podporováno integrovanými funkcemi. Získání podobného chování
System.Text.Json
může vyžadovat použití atributu nebo globální možnosti. - ⚠✔ Nepodporováno, ale alternativní řešení je možné. Alternativní řešení jsou vlastní převaděče, které nemusí poskytovat úplnou paritu s funkcemi
Newtonsoft.Json
. Pro některé z nich je ukázkový kód k dispozici jako příklady. Pokud se na tytoNewtonsoft.Json
funkce spoléháte, migrace bude vyžadovat úpravy vašich objektů .NET nebo jiných změn kódu. - ❌ Nepodporuje se a alternativní řešení není praktické nebo možné. Pokud se na tyto
Newtonsoft.Json
funkce spoléháte, migrace nebude možná bez významných změn.
Funkce systému Newtonsoft.Json | System.Text.Json ekvivalentní |
---|---|
Ve výchozím nastavení se nerozlišují malá a velká písmena | ✔️ Globální nastavení PropertyNameCaseInsensitive |
Názvy vlastností camel-case | ✔️ Globální nastavení PropertyNamingPolicy |
Názvy vlastností hadího případu | ✔️ Zásady pojmenování hadího případu |
Minimální znakové zapouzdření | ✔️ Striktní zapouzdření znaků, konfigurovatelné |
NullValueHandling.Ignore globální nastavení |
✔️ Globální možnost DefaultIgnoreCondition |
Povolit komentáře | ✔️ Globální nastavení ReadCommentHandling |
Povolit koncové čárky | ✔️ Globální nastavení AllowTrailingCommas |
Registrace vlastního převaděče | ✔️ Pořadí priorit se liší |
Výchozí maximální hloubka 64, konfigurovatelná | ✔️ Výchozí maximální hloubka 64, konfigurovatelná |
PreserveReferencesHandling globální nastavení |
✔️ Globální nastavení ReferenceHandling |
Serializace nebo deserializace čísel v uvozovkách | ✔️ Globální nastavení NumberHandling, atribut [JsonNumberHandling] |
Deserializace na neměnné třídy a struktury | ✔️ JsonConstructor, C# 9 Records |
Podpora polí | ✔️ Globální nastavení IncludeFields, atribut [JsonInclude] |
DefaultValueHandling globální nastavení |
✔️ Globální nastavení DefaultIgnoreCondition |
NullValueHandling nastavení zapnuto [JsonProperty] |
✔️ Atribut JsonIgnore |
DefaultValueHandling nastavení zapnuto [JsonProperty] |
✔️ Atribut JsonIgnore |
Deserializace Dictionary s klíčem bez řetězce |
✔️ Podporovaný |
Podpora neveřejných objektů setter a getters | ✔️ Atribut JsonInclude |
Atribut [JsonConstructor] |
✔️ [JsonConstructor] – atribut |
ReferenceLoopHandling globální nastavení |
✔️ Globální nastavení ReferenceHandling |
Zpětná volání | ✔️ Zpětných volání |
NaN, Nekonečno, -Nekonečno | ✔️ Podporovaný |
Required nastavení atributu [JsonProperty] |
✔️ Atribut [JsonRequired] a požadovaný modifikátor jazyka C# |
DefaultContractResolver ignorování vlastností |
✔️ DefaultJsonTypeInfoResolver – třída |
Polymorfní serializace | ✔️ Atribut [JsonDerivedType] |
Polymorfní deserializace | ✔️ Diskriminátor typů u atributu [JsonDerivedType] |
Deserializace hodnoty výčtu řetězce | ✔️ Deserializace hodnot výčtu řetězců |
MissingMemberHandling globální nastavení |
✔️ Zpracování chybějících členů |
Naplnění vlastností bez zatřikování | ✔️ Naplnění vlastností bez zatřikování |
ObjectCreationHandling globální nastavení |
✔️ Opakované použití místo nahrazení vlastností |
Podpora široké škály typů | ⚠️ Některé typy vyžadují vlastní převaděče. |
Deserializovat odvozený typ na object vlastnosti |
⚠️ Nepodporováno, alternativní řešení, ukázka |
Deserializace literálu JSON null na typy hodnot bez hodnoty null |
⚠️ Nepodporováno, alternativní řešení, ukázka |
DateTimeZoneHandling , DateFormatString nastavení |
⚠️ Nepodporováno, alternativní řešení, ukázka |
JsonConvert.PopulateObject metoda |
⚠️ Nepodporováno, alternativní řešení |
Podpora atributů System.Runtime.Serialization |
⚠️ Nepodporováno, alternativní řešení, ukázka |
JsonObjectAttribute |
⚠️ Nepodporováno, alternativní řešení |
Povolit názvy vlastností bez uvozovek | ❌Návrh nepodporuje |
Povolit jednoduché uvozovky kolem řetězcových hodnot | ❌Návrh nepodporuje |
Povolit neřetězcové hodnoty JSON pro vlastnosti řetězce | ❌Návrh nepodporuje |
TypeNameHandling.All globální nastavení |
❌Návrh nepodporuje |
Podpora dotazů JsonPath |
❌Nepodporováno |
Konfigurovatelné limity | ❌Nepodporováno |
Funkce systému Newtonsoft.Json | System.Text.Json ekvivalentní |
---|---|
Ve výchozím nastavení se nerozlišují malá a velká písmena | ✔️ Globální nastavení PropertyNameCaseInsensitive |
Názvy vlastností camel-case | ✔️ Globální nastavení PropertyNamingPolicy |
Minimální znakové zapouzdření | ✔️ Striktní zapouzdření znaků, konfigurovatelné |
NullValueHandling.Ignore globální nastavení |
✔️ Globální možnost DefaultIgnoreCondition |
Povolit komentáře | ✔️ Globální nastavení ReadCommentHandling |
Povolit koncové čárky | ✔️ Globální nastavení AllowTrailingCommas |
Registrace vlastního převaděče | ✔️ Pořadí priorit se liší |
Výchozí maximální hloubka 64, konfigurovatelná | ✔️ Výchozí maximální hloubka 64, konfigurovatelná |
PreserveReferencesHandling globální nastavení |
✔️ Globální nastavení ReferenceHandling |
Serializace nebo deserializace čísel v uvozovkách | ✔️ Globální nastavení NumberHandling, atribut [JsonNumberHandling] |
Deserializace na neměnné třídy a struktury | ✔️ JsonConstructor, C# 9 Records |
Podpora polí | ✔️ Globální nastavení IncludeFields, atribut [JsonInclude] |
DefaultValueHandling globální nastavení |
✔️ Globální nastavení DefaultIgnoreCondition |
NullValueHandling nastavení zapnuto [JsonProperty] |
✔️ Atribut JsonIgnore |
DefaultValueHandling nastavení zapnuto [JsonProperty] |
✔️ Atribut JsonIgnore |
Deserializace Dictionary s klíčem bez řetězce |
✔️ Podporovaný |
Podpora neveřejných objektů setter a getters | ✔️ Atribut JsonInclude |
Atribut [JsonConstructor] |
✔️ [JsonConstructor] – atribut |
ReferenceLoopHandling globální nastavení |
✔️ Globální nastavení ReferenceHandling |
Zpětná volání | ✔️ Zpětných volání |
NaN, Nekonečno, -Nekonečno | ✔️ Podporovaný |
Required nastavení atributu [JsonProperty] |
✔️ Atribut [JsonRequired] a požadovaný modifikátor jazyka C# |
DefaultContractResolver ignorování vlastností |
✔️ DefaultJsonTypeInfoResolver – třída |
Polymorfní serializace | ✔️ Atribut [JsonDerivedType] |
Polymorfní deserializace | ✔️ Diskriminátor typů u atributu [JsonDerivedType] |
Deserializace hodnoty výčtu řetězce | ✔️ Deserializace hodnot výčtu řetězců |
Podpora široké škály typů | ⚠️ Některé typy vyžadují vlastní převaděče. |
Deserializovat odvozený typ na object vlastnosti |
⚠️ Nepodporováno, alternativní řešení, ukázka |
Deserializace literálu JSON null na typy hodnot bez hodnoty null |
⚠️ Nepodporováno, alternativní řešení, ukázka |
DateTimeZoneHandling , DateFormatString nastavení |
⚠️ Nepodporováno, alternativní řešení, ukázka |
JsonConvert.PopulateObject metoda |
⚠️ Nepodporováno, alternativní řešení |
ObjectCreationHandling globální nastavení |
⚠️ Nepodporováno, alternativní řešení |
Přidání do kolekcí bez setter | ⚠️ Nepodporováno, alternativní řešení |
Názvy vlastností hadího případu | ⚠️ Nepodporováno, alternativní řešení |
Podpora atributů System.Runtime.Serialization |
⚠️ Nepodporováno, alternativní řešení, ukázka |
MissingMemberHandling globální nastavení |
⚠️ Nepodporováno, alternativní řešení, ukázka |
JsonObjectAttribute |
⚠️ Nepodporováno, alternativní řešení |
Povolit názvy vlastností bez uvozovek | ❌Návrh nepodporuje |
Povolit jednoduché uvozovky kolem řetězcových hodnot | ❌Návrh nepodporuje |
Povolit neřetězcové hodnoty JSON pro vlastnosti řetězce | ❌Návrh nepodporuje |
TypeNameHandling.All globální nastavení |
❌Návrh nepodporuje |
Podpora dotazů JsonPath |
❌Nepodporováno |
Konfigurovatelné limity | ❌Nepodporováno |
Funkce systému Newtonsoft.Json | System.Text.Json ekvivalentní |
---|---|
Ve výchozím nastavení se nerozlišují malá a velká písmena | ✔️ Globální nastavení PropertyNameCaseInsensitive |
Názvy vlastností camel-case | ✔️ Globální nastavení PropertyNamingPolicy |
Minimální znakové zapouzdření | ✔️ Striktní zapouzdření znaků, konfigurovatelné |
NullValueHandling.Ignore globální nastavení |
✔️ Globální možnost DefaultIgnoreCondition |
Povolit komentáře | ✔️ Globální nastavení ReadCommentHandling |
Povolit koncové čárky | ✔️ Globální nastavení AllowTrailingCommas |
Registrace vlastního převaděče | ✔️ Pořadí priorit se liší |
Výchozí maximální hloubka 64, konfigurovatelná | ✔️ Výchozí maximální hloubka 64, konfigurovatelná |
PreserveReferencesHandling globální nastavení |
✔️ Globální nastavení ReferenceHandling |
Serializace nebo deserializace čísel v uvozovkách | ✔️ Globální nastavení NumberHandling, atribut [JsonNumberHandling] |
Deserializace na neměnné třídy a struktury | ✔️ JsonConstructor, C# 9 Records |
Podpora polí | ✔️ Globální nastavení IncludeFields, atribut [JsonInclude] |
DefaultValueHandling globální nastavení |
✔️ Globální nastavení DefaultIgnoreCondition |
NullValueHandling nastavení zapnuto [JsonProperty] |
✔️ Atribut JsonIgnore |
DefaultValueHandling nastavení zapnuto [JsonProperty] |
✔️ Atribut JsonIgnore |
Deserializace Dictionary s klíčem bez řetězce |
✔️ Podporovaný |
Podpora neveřejných objektů setter a getters | ✔️ Atribut JsonInclude |
Atribut [JsonConstructor] |
✔️ [JsonConstructor] – atribut |
ReferenceLoopHandling globální nastavení |
✔️ Globální nastavení ReferenceHandling |
Zpětná volání | ✔️ Zpětných volání |
NaN, Nekonečno, -Nekonečno | ✔️ Podporovaný |
Deserializace hodnoty výčtu řetězce | ✔️ Deserializace hodnot výčtu řetězců |
Podpora široké škály typů | ⚠️ Některé typy vyžadují vlastní převaděče. |
Polymorfní serializace | ⚠️ Nepodporováno, alternativní řešení, ukázka |
Polymorfní deserializace | ⚠️ Nepodporováno, alternativní řešení, ukázka |
Deserializovat odvozený typ na object vlastnosti |
⚠️ Nepodporováno, alternativní řešení, ukázka |
Deserializace literálu JSON null na typy hodnot bez hodnoty null |
⚠️ Nepodporováno, alternativní řešení, ukázka |
Required nastavení atributu [JsonProperty] |
⚠️ Nepodporováno, alternativní řešení, ukázka |
DefaultContractResolver ignorování vlastností |
⚠️ Nepodporováno, alternativní řešení, ukázka |
DateTimeZoneHandling , DateFormatString nastavení |
⚠️ Nepodporováno, alternativní řešení, ukázka |
JsonConvert.PopulateObject metoda |
⚠️ Nepodporováno, alternativní řešení |
ObjectCreationHandling globální nastavení |
⚠️ Nepodporováno, alternativní řešení |
Přidání do kolekcí bez setter | ⚠️ Nepodporováno, alternativní řešení |
Názvy vlastností hadího případu | ⚠️ Nepodporováno, alternativní řešení |
JsonObjectAttribute |
⚠️ Nepodporováno, alternativní řešení |
Podpora atributů System.Runtime.Serialization |
❌Nepodporováno |
MissingMemberHandling globální nastavení |
❌Nepodporováno |
Povolit názvy vlastností bez uvozovek | ❌Návrh nepodporuje |
Povolit jednoduché uvozovky kolem řetězcových hodnot | ❌Návrh nepodporuje |
Povolit neřetězcové hodnoty JSON pro vlastnosti řetězce | ❌Návrh nepodporuje |
TypeNameHandling.All globální nastavení |
❌Návrh nepodporuje |
Podpora dotazů JsonPath |
❌Nepodporováno |
Konfigurovatelné limity | ❌Nepodporováno |
Nejedná se o vyčerpávající seznam Newtonsoft.Json
funkcí. Seznam obsahuje řadu scénářů, které byly požadovány v problémech GitHubu nebo příspěvcích StackOverflow . Pokud implementujete alternativní řešení pro některý z zde uvedených scénářů, které aktuálně nemají vzorový kód, a pokud chcete své řešení sdílet, vyberte tuto stránku v části Váš názor v dolní části této stránky. Tím se v úložišti GitHubu této dokumentace vytvoří problém a vypíše ho také v části Váš názor na této stránce.
Rozdíly ve výchozím chování
System.Text.Json je ve výchozím nastavení striktní a zabraňuje jakémukoli odhadu nebo interpretaci jménem volajícího a zdůrazňuje deterministické chování. Knihovna je záměrně navržena tak, aby byla určena pro výkon a zabezpečení. Newtonsoft.Json
je ve výchozím nastavení flexibilní. Tento základní rozdíl v návrhu je za mnoha z následujících specifických rozdílů ve výchozím chování.
Nerozlišující velká a malá písmena deserializace
Během deserializace Newtonsoft.Json
nerozlišuje ve výchozím nastavení název vlastnosti nerozlišující velká a malá písmena. Ve System.Text.Json výchozím nastavení se rozlišují malá a velká písmena, což poskytuje lepší výkon, protože provádí přesnou shodu. Informace o tom, jak rozlišovat malá a velká písmena porovnávání, naleznete v tématu Porovnávání vlastností bez rozlišování velkých a malých písmen.
Pokud používáte System.Text.Json
nepřímo ASP.NET Core, nemusíte dělat nic, abyste získali podobné chování Newtonsoft.Json
. ASP.NET Core určuje nastavení pro názvy vlastností camel-casing a porovnávání nerozlišující malá a velká písmena při použití System.Text.Json
.
ASP.NET Core také ve výchozím nastavení umožňuje deserializaci uvozových čísel .
Minimální znakové zapouzdření
Během serializace Newtonsoft.Json
je relativně permisivní o nechat znaky procházet bez jejich úniku. To znamená, že je nenahrazuje místem \uxxxx
, kde xxxx
je znakový bod. Když je řídicí, provede to tak, že vygeneruje znak před znakem \
(například "
se stane \"
). System.Text.Json ve výchozím nastavení uchycuje více znaků, aby poskytovaly hloubkovou ochranu před skriptováním mezi weby (XSS) nebo útoky na zpřístupnění informací a dělá to pomocí šestiznakových sekvencí. System.Text.Json
ve výchozím nastavení uchycuje všechny znaky jiné než ASCII, takže nemusíte dělat nic, pokud používáte StringEscapeHandling.EscapeNonAscii
Newtonsoft.Json
. System.Text.Json
ve výchozím nastavení také umistuje znaky citlivé na HTML. Informace o přepsání výchozího System.Text.Json
chování naleznete v tématu Přizpůsobení kódování znaků.
Komentáře
Během deserializace Newtonsoft.Json
ignoruje komentáře ve formátu JSON ve výchozím nastavení. Výchozí System.Text.Json hodnotou je vyvolání výjimek pro komentáře, protože specifikace RFC 8259 je neobsahuje. Informace o tom, jak povolit komentáře, naleznete v tématu Povolit komentáře a koncové čárky.
Koncové čárky
Během deserializace Newtonsoft.Json
ignoruje koncové čárky ve výchozím nastavení. Ignoruje také více koncových čárek (například [{"Color":"Red"},{"Color":"Green"},,]
). Výchozí System.Text.Json hodnotou je vyvolání výjimek pro koncové čárky, protože specifikace RFC 8259 je neumožňuje. Informace o tom System.Text.Json
, jak je přijmout, najdete v tématu Povolit komentáře a koncové čárky. Není možné povolit více koncových čárek.
Priorita registrace převaděče
Priorita Newtonsoft.Json
registrace pro vlastní převaděče je následující:
- Atribut u vlastnosti
- Atribut typu
- Kolekce převaděčů
Toto pořadí znamená, že vlastní převaděč v Converters
kolekci je přepsán převaděčem registrovaným použitím atributu na úrovni typu. Obě tyto registrace jsou přepsány atributem na úrovni vlastnosti.
Priorita System.Text.Json registrace pro vlastní převaděče se liší:
- Atribut u vlastnosti
- Converters sbírka
- Atribut typu
Rozdíl je v tom, že vlastní převaděč v Converters
kolekci přepíše atribut na úrovni typu. Záměrem za tímto pořadím priority je provést změny za běhu, které přepíší návrhové volby. Neexistuje způsob, jak změnit prioritu.
Další informace o registraci vlastního převaděče naleznete v tématu Registrace vlastního převaděče.
Maximální hloubka
Nejnovější verze Newtonsoft.Json
má ve výchozím nastavení maximální limit hloubky 64. System.Text.Json má také výchozí limit 64 a je konfigurovatelný nastavením JsonSerializerOptions.MaxDepth.
Pokud používáte System.Text.Json
nepřímo ASP.NET Core, výchozí limit maximální hloubky je 32. Výchozí hodnota je stejná jako pro vazbu modelu a je nastavena ve třídě JsonOptions.
Řetězce JSON (názvy vlastností a řetězcové hodnoty)
Během deserializace Newtonsoft.Json
přijímá názvy vlastností obklopené dvojitými uvozovkami, jednoduchými uvozovkami nebo bez uvozovek. Přijímá řetězcové hodnoty obklopené dvojitými uvozovkami nebo jednoduchými uvozovkami. Například Newtonsoft.Json
přijímá následující kód JSON:
{
"name1": "value",
'name2': "value",
name3: 'value'
}
System.Text.Json
Přijímá pouze názvy vlastností a řetězcové hodnoty v dvojitých uvozovkách, protože tento formát je vyžadován specifikací RFC 8259 a je jediným formátem považován za platný JSON.
Výsledkem hodnoty uzavřené v jednoduchých uvozovkách je výjimka JsonException s následující zprávou:
''' is an invalid start of a value.
Neřetězcové hodnoty pro vlastnosti řetězce
Newtonsoft.Json
přijímá neřetězcové hodnoty, například číslo nebo literály true
a false
, pro deserializaci na vlastnosti typu řetězec. Tady je příklad kódu JSON, který Newtonsoft.Json
úspěšně deserializuje následující třídu:
{
"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
nekonstrukční hodnoty deserializuje do vlastností řetězce. Hodnota, která není řetězec přijatá pro pole řetězce, má za následek hodnotu JsonException s následující zprávou:
The JSON value could not be converted to System.String.
Scénáře s využitím JsonSerializeru
Některé z následujících scénářů nejsou integrované funkce podporované, ale alternativní řešení jsou možná. Alternativní řešení jsou vlastní převaděče, které nemusí poskytovat úplnou paritu s funkcemi Newtonsoft.Json
. Pro některé z nich je ukázkový kód k dispozici jako příklady. Pokud se na tyto Newtonsoft.Json
funkce spoléháte, migrace bude vyžadovat úpravy vašich objektů .NET nebo jiných změn kódu.
V některých z následujících scénářů nejsou alternativní řešení praktická nebo možná. Pokud se na tyto Newtonsoft.Json
funkce spoléháte, migrace nebude možná bez významných změn.
Povolit nebo zapsat čísla v uvozovkách
Newtonsoft.Json
může serializovat nebo deserializovat čísla reprezentovaná řetězci JSON (obklopené uvozovkami). Může například přijmout: {"DegreesCelsius":"23"}
místo {"DegreesCelsius":23}
. Pokud chcete toto chování povolit, System.Text.Jsonnastavte JsonSerializerOptions.NumberHandling na WriteAsString hodnotu nebo AllowReadingFromStringpoužijte atribut [JsonNumberHandling].
Pokud používáte System.Text.Json
nepřímo ASP.NET Core, nemusíte dělat nic, abyste získali podobné chování Newtonsoft.Json
. ASP.NET Core určuje výchozí hodnoty webu při použití System.Text.Json
a výchozí hodnoty webu umožňují uvozovávání čísel.
Další informace najdete v tématu Povolení nebo zápis čísel v uvozovkách.
Určení konstruktoru, který se má použít při deserializaci
Atribut Newtonsoft.Json
[JsonConstructor]
umožňuje určit, který konstruktor má volat při deserializaci do POCO.
System.Text.Json
má také atribut [JsonConstructor]. Další informace naleznete v tématu Neměnné typy a záznamy.
Podmíněně ignorovat vlastnost
Newtonsoft.Json
má několik způsobů, jak podmíněně ignorovat vlastnost serializace nebo deserializace:
DefaultContractResolver
umožňuje vybrat vlastnosti, které chcete zahrnout nebo ignorovat na základě libovolných kritérií.- Toto
NullValueHandling
nastaveníJsonSerializerSettings
vámDefaultValueHandling
umožní určit, že se mají ignorovat všechny vlastnosti s hodnotou null nebo výchozí hodnotou. - Nastavení
NullValueHandling
atributuDefaultValueHandling
[JsonProperty]
umožňují určit jednotlivé vlastnosti, které by se měly ignorovat při nastavení hodnoty null nebo výchozí hodnoty.
System.Text.Json poskytuje následující způsoby, jak při serializaci ignorovat vlastnosti nebo pole:
- Atribut [JsonIgnore] u vlastnosti způsobí, že vlastnost bude během serializace vynechána z JSON.
- Globální možnost IgnoreReadOnlyProperties umožňuje ignorovat všechny vlastnosti jen pro čtení.
- Pokud zahrnete pole, JsonSerializerOptions.IgnoreReadOnlyFields globální možnost umožňuje ignorovat všechna pole jen pro čtení.
- Globální
DefaultIgnoreCondition
možnost umožňuje ignorovat všechny vlastnosti typu hodnoty, které mají výchozí hodnoty, nebo ignorovat všechny vlastnosti typu odkazu, které mají hodnoty null.
Kromě toho můžete v .NET 7 a novějších verzích přizpůsobit kontrakt JSON tak, aby ignoroval vlastnosti na základě libovolných kritérií. Další informace naleznete v tématu Vlastní kontrakty.
Tyto možnosti nedovolují ignorovat vybrané vlastnosti na základě libovolných kritérií vyhodnocených za běhu.
Veřejná a neveřejná pole
Newtonsoft.Json
může serializovat a deserializovat pole i vlastnosti.
Použijte System.Text.Jsonglobální JsonSerializerOptions.IncludeFields nastavení nebo atribut [JsonInclude] k zahrnutí veřejných polí při serializaci nebo deserializaci. Příklad najdete v části Zahrnout pole.
Zachování odkazů na objekt a zpracování smyček
Ve výchozím nastavení Newtonsoft.Json
serializuje podle hodnoty. Pokud například objekt obsahuje dvě vlastnosti, které obsahují odkaz na stejný Person
objekt, budou hodnoty Person
vlastností tohoto objektu duplikovány ve formátu JSON.
Newtonsoft.Json
PreserveReferencesHandling
má nastaveníJsonSerializerSettings
, které umožňuje serializovat odkazem:
- Metadata identifikátoru se přidají do formátu JSON vytvořeného pro první
Person
objekt. - Json vytvořený pro druhý
Person
objekt obsahuje odkaz na tento identifikátor místo hodnot vlastností.
Newtonsoft.Json
má ReferenceLoopHandling
také nastavení, které umožňuje ignorovat cyklické odkazy místo vyvolání výjimky.
Chcete-li zachovat odkazy a zpracovat cyklické odkazy v System.Text.Json, je nastavena JsonSerializerOptions.ReferenceHandler na Preservehodnotu . Nastavení ReferenceHandler.Preserve
je ekvivalentní hodnotě PreserveReferencesHandling
= PreserveReferencesHandling.All
in Newtonsoft.Json
.
Možnost ReferenceHandler.IgnoreCycles
má podobné chování jako Newtonsoft.JsonReferenceLoopHandling.Ignore
. Jedním rozdílem je, že System.Text.Json implementace nahrazuje smyčky odkazů tokenem null
JSON místo ignorování odkazu na objekt. Další informace najdete v tématu Ignorování cyklických odkazů.
Newtonsoft.JsonPodobně jako ReferenceResolverSystem.Text.Json.Serialization.ReferenceResolver třída definuje chování zachování odkazů na serializaci a deserializaci. Vytvořte odvozenou třídu pro určení vlastního chování. Příklad najdete v tématu GuidReferenceResolver.
Některé související Newtonsoft.Json
funkce nejsou podporované:
Další informace naleznete v tématu Zachování odkazů a zpracování cyklických odkazů.
Slovník s klíčem bez řetězce
Obě Newtonsoft.Json
a System.Text.Json
podporují kolekce typu Dictionary<TKey, TValue>
. Musí System.Text.Json
TKey
však být primitivním typem, nikoli vlastním typem. Další informace naleznete v tématu Podporované typy klíčů.
Upozornění
Deserializace na místo, Dictionary<TKey, TValue>
kde TKey
je zadáno jako cokoli jiného, než string
by mohlo v aplikaci, která využívá, představovat ohrožení zabezpečení. Další informace najdete v tématu dotnet/runtime#4761.
Typy bez integrované podpory
System.Text.Json neposkytuje integrovanou podporu pro následující typy:
- DataTable a související typy (další informace najdete v tématu Podporované typy kolekcí)
- ExpandoObject
- TimeZoneInfo
- BigInteger
- DBNull
- Type
- ValueTuple a jeho přidružené obecné typy
Vlastní převaděče je možné implementovat pro typy, které nemají integrovanou podporu.
Polymorfní serializace
Newtonsoft.Json
automaticky provádí polymorfní serializaci. Počínaje rozhraním .NET 7 System.Text.Json podporuje polymorfní serializaci prostřednictvím atributu JsonDerivedTypeAttribute . Další informace naleznete v tématu Serializace vlastností odvozených tříd.
Polymorfní deserializace
Newtonsoft.Json
TypeNameHandling
má nastavení, které při serializaci přidává metadata názvu typu do formátu JSON. Používá metadata při deserializaci k polymorfní deserializaci. Počínaje rozhraním .NET 7 System.Text.Json se při provádění polymorfní deserializace spoléhá na diskriminující informace o typu. Tato metadata se vygenerují ve formátu JSON a použijí se při deserializaci k určení, zda se má deserializovat na základní typ nebo odvozený typ. Další informace naleznete v tématu Serializace vlastností odvozených tříd.
Chcete-li podporovat polymorfní deserializaci ve starších verzích .NET, vytvořte převaděč, jako je příklad v návodu k zápisu vlastních převaděčů.
Deserializace hodnot výčtu řetězců
Ve výchozím nastavení System.Text.Json nepodporuje deserializaci hodnot výčtu řetězců, zatímco Newtonsoft.Json
to dělá. Například následující kód vyvolá 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
}
Pomocí převaděče však můžete povolit deserializaci hodnot výčtu JsonStringEnumConverter řetězců. Další informace naleznete v tématu Výčty jako řetězce.
Deserializace vlastností objektu
Při Newtonsoft.Json
deserializaci na Object, to:
- Odvodí typ primitivních hodnot v datové části JSON (jiné než
null
) a vrátí uloženoustring
hodnotu ,long
,double
,boolean
neboDateTime
jako boxovaný objekt. Primitivní hodnoty jsou jednoduché hodnoty JSON, jako je číslo JSON, řetězec,true
,false
nebonull
. JObject
Vrátí hodnotu neboJArray
pro komplexní hodnoty v datové části JSON. Komplexní hodnoty jsou kolekce párů klíč-hodnota JSON v rámci složených závorek ({}
) nebo seznamů hodnot v hranatých závorkách ([]
). Vlastnosti a hodnoty v závorkách nebo závorkách můžou mít další vlastnosti nebo hodnoty.- Vrátí nulový odkaz, pokud datová část obsahuje
null
literál JSON.
System.Text.Json ukládá rámečky JsonElement
pro primitivní i komplexní hodnoty při každé deserializaci Objectna , například:
- Vlastnost
object
. - Hodnota
object
slovníku. - Jedná se o maticovou
object
hodnotu. - Kořen
object
.
System.Text.Json
Považuje null
však za stejný Newtonsoft.Json
jako a vrátí nulový odkaz, pokud datová část obsahuje null
literál JSON.
Chcete-li implementovat odvození typu pro object
vlastnosti, vytvořte převaděč, jako je příklad v postupu zápisu vlastních převaděčů.
Deserializace typu null na typ bez hodnoty null
Newtonsoft.Json
nevyvolá výjimku v následujícím scénáři:
NullValueHandling
je nastavena naIgnore
hodnotu a- Během deserializace json obsahuje hodnotu null pro typ hodnoty bez hodnoty null.
Ve stejném scénáři System.Text.Json vyvolá výjimku. (Odpovídající nastavení zpracování null je JsonSerializerOptions.IgnoreNullValues = true
.)System.Text.Json
Pokud vlastníte cílový typ, nejlepším alternativním řešením je vytvořit vlastnost s možnou hodnotou null (například změnit int
na int?
).
Dalším alternativním řešením je vytvořit převaděč pro typ, například následující příklad, který zpracovává hodnoty null pro DateTimeOffset
typy:
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);
}
}
Zaregistrujte tento vlastní převaděč pomocí atributu ve vlastnosti nebo přidáním převaděče Converters do kolekce.
Poznámka: Předchozí převaděč zpracovává hodnoty null odlišně než Newtonsoft.Json
u objektů POCOs, které určují výchozí hodnoty. Předpokládejme například, že následující kód představuje cílový objekt:
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; }
}
A předpokládejme, že následující JSON je deserializován pomocí předchozího převaděče:
{
"Date": null,
"TemperatureCelsius": 25,
"Summary": null
}
Po deserializaci Date
má vlastnost hodnotu 1/1/0001 (default(DateTimeOffset)
), tj. hodnota nastavená v konstruktoru je přepsána. Vzhledem ke stejnému POCO a JSON Newtonsoft.Json
by deserializace ponechá ve Date
vlastnosti 1.1.2001.
Deserializace na neměnné třídy a struktury
Newtonsoft.Json
může deserializovat na neměnné třídy a struktury, protože může používat konstruktory, které mají parametry.
Pomocí System.Text.Jsonatributu [JsonConstructor] zadejte použití parametrizovaného konstruktoru. Záznamy v jazyce C# 9 jsou také neměnné a podporují se jako cíle deserializace. Další informace naleznete v tématu Neměnné typy a záznamy.
Požadované vlastnosti
V Newtonsoft.Json
parametru určíte, že vlastnost je vyžadována nastavením Required
atributu [JsonProperty]
. Newtonsoft.Json
vyvolá výjimku, pokud ve formátu JSON není přijata žádná hodnota pro vlastnost označenou jako povinnou.
Počínaje rozhraním .NET 7 můžete použít modifikátor jazyka C# required
nebo JsonRequiredAttribute atribut u požadované vlastnosti. System.Text.Json vyvolá výjimku, pokud datová část JSON neobsahuje hodnotu pro označenou vlastnost. Další informace naleznete v tématu Povinné vlastnosti.
System.Text.Json vyvolá výjimku, pokud není přijata žádná hodnota pro jednu z vlastností cílového typu. Pokud máte WeatherForecast
například třídu:
public class WeatherForecast
{
public DateTimeOffset Date { get; set; }
public int TemperatureCelsius { get; set; }
public string? Summary { get; set; }
}
Následující json je deserializován bez chyby:
{
"TemperatureCelsius": 25,
"Summary": "Hot"
}
Pokud chcete, aby deserializace selhala, pokud ve formátu JSON není žádná Date
vlastnost, zvolte jednu z následujících možností:
- Použijte .NET 7 nebo novější verzi System.Text.Json balíčku a přidejte
required
modifikátor (dostupný od jazyka C# 11) nebo JsonRequiredAttribute atribut do vlastnosti. - Implementujte vlastní převaděč.
OnDeserialized
Implementujte zpětné volání (.NET 6 a novější).
Následující ukázkový kód převaděče vyvolá výjimku, pokud Date
vlastnost není nastavena po dokončení deserializace:
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);
}
}
}
Zaregistrujte tento vlastní převaděč přidáním převaděče JsonSerializerOptions.Converters do kolekce.
Tento model rekurzivního volání převaděče vyžaduje, abyste převaděč registrovali pomocí JsonSerializerOptions, ne pomocí atributu. Pokud převaděč zaregistrujete pomocí atributu, vlastní převaděč rekurzivně volá sám sebe. Výsledkem je nekonečná smyčka, která končí výjimkou přetečení zásobníku.
Při registraci převaděče pomocí objektu options, vyhněte se nekonečné smyčce tím, že nepředávejte objekt možnosti objekt při rekurzivním volání Serialize nebo Deserialize. Objekt options obsahuje kolekci Converters . Pokud ho Serialize
předáte nebo Deserialize
, vlastní převaděč volá do sebe, vytvoření nekonečné smyčky, která vede k výjimce zásobníku přetečení. Pokud výchozí možnosti nejsou proveditelné, vytvořte novou instanci možností s požadovanými nastaveními. Tento přístup bude pomalý, protože každá nová instance ukládá do mezipaměti nezávisle.
Existuje alternativní vzor, který může použít JsonConverterAttribute
registraci třídy, která se má převést. V tomto přístupu kód převaděče volá Serialize
nebo Deserialize
třídy, která je odvozena od třídy, která má být převedena. Odvozená třída na ni nemá použitou JsonConverterAttribute
. V následujícím příkladu této alternativy:
WeatherForecastWithRequiredPropertyConverterAttribute
je třída, která má být deserializována a máJsonConverterAttribute
na ni použito.WeatherForecastWithoutRequiredPropertyConverterAttribute
je odvozená třída, která nemá atribut converter.- Kód v převaděči volá
Serialize
aDeserialize
zapnutoWeatherForecastWithoutRequiredPropertyConverterAttribute
, aby se zabránilo nekonečné smyčce. Tento přístup má při serializaci náklady na výkon kvůli vytvoření instance objektu a kopírování hodnot vlastností.
Tady jsou typy WeatherForecast*
:
[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
{
}
A tady je převaděč:
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);
}
}
}
Převaděč požadovaných vlastností by vyžadoval další logiku, pokud potřebujete zpracovat atributy, jako je [JsonIgnore] nebo jiné možnosti, jako jsou vlastní kodéry. Příklad kódu také nezpracuje vlastnosti, pro které je v konstruktoru nastavena výchozí hodnota. A tento přístup nerozlišuje mezi následujícími scénáři:
- Ve formátu JSON chybí vlastnost.
- Ve formátu JSON se nachází vlastnost jiného typu než null, ale hodnota je výchozí hodnotou pro typ, například nula pro typ
int
. - Vlastnost pro typ hodnoty s možnou hodnotou null se nachází ve formátu JSON, ale hodnota má hodnotu null.
Poznámka:
Pokud používáte System.Text.Json řadič ASP.NET Core, možná budete moct místo implementace System.Text.Json převaděče použít [Required]
atribut u vlastností třídy modelu.
Zadání formátu data
Newtonsoft.Json
poskytuje několik způsobů řízení, jak vlastnosti DateTime
a DateTimeOffset
typy jsou serializovány a deserializovány:
- Nastavení
DateTimeZoneHandling
lze použít k serializaci všechDateTime
hodnot jako data UTC. - Nastavení
DateFormatString
aDateTime
převaděče lze použít k přizpůsobení formátu řetězců kalendářních dat.
System.Text.Json podporuje ISO 8601-1:2019 včetně profilu RFC 3339. Tento formát je široce přijímaný, jednoznačný a provádí přesné odezvy. Pokud chcete použít jiný formát, vytvořte vlastní převaděč. Například následující převaděče serializují a deserializují JSON, které používají formát Epoch unixu s posunem časového pásma (hodnoty, jako /Date(1590863400000-0700)/
jsou nebo /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);
}
}
Další informace naleznete v tématu DateTime a DateTimeOffset podpora v System.Text.Json.
Zpětná volání
Newtonsoft.Json
umožňuje spouštět vlastní kód v několika bodech procesu serializace nebo deserializace:
- OnDeserializing (při zahájení deserializace objektu)
- OnDeserialized (po dokončení deserializace objektu)
- OnSerializing (při zahájení serializace objektu)
- OnSerialized (po dokončení serializace objektu)
System.Text.Json zveřejňuje stejná oznámení během serializace a deserializace. Pokud je chcete použít, implementujte jedno nebo více následujících rozhraní z System.Text.Json.Serialization oboru názvů:
Tady je příklad, který kontroluje vlastnost null a zapisuje zprávy na začátku a na konci serializace a deserializace:
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=
Kód OnDeserializing
nemá přístup k nové instanci POCO. Chcete-li manipulovat s novou instancí POCO na začátku deserializace, vložte tento kód do konstruktoru POCO.
Neveřejná vlastnost setters a getters
Newtonsoft.Json
může používat privátní a interní vlastnosti setters a getters prostřednictvím atributu JsonProperty
.
System.Text.Jsonpodporuje privátní a interní setters a getters prostřednictvím atributu [JsonInclude]. Vzorový kód naleznete v tématu Neveřejné přístupové objekty vlastností.
Naplnění existujících objektů
Metoda JsonConvert.PopulateObject
deserializuje Newtonsoft.Json
dokument JSON do existující instance třídy místo vytvoření nové instance. System.Text.Json vždy vytvoří novou instanci cílového typu pomocí výchozího veřejného konstruktoru bez parametrů. Vlastní převaděče mohou deserializovat na existující instanci.
Opakované použití místo nahrazení vlastností
Počínaje rozhraním .NET 8 System.Text.Json podporuje opakované použití inicializovaných vlastností, nikoli jejich nahrazení. Existují určité rozdíly v chování, o kterých si můžete přečíst v návrhu rozhraní API.
Další informace naleznete v tématu Naplnění inicializovaných vlastností.
Nastavení ObjectCreationHandling
Newtonsoft.Json
v umožňuje určit, že objekty ve vlastnostech by se měly znovu použít místo nahrazení během deserializace. System.Text.Json vždy nahrazuje objekty ve vlastnostech. Vlastní převaděče můžou tuto funkci poskytovat nebo můžete upgradovat na .NET 8, která poskytuje naplnit funkce.
Naplnění vlastností bez zatřikování
Počínaje rozhraním .NET 8 System.Text.Json podporuje naplnění vlastností, včetně těch, které nemají setter. Další informace naleznete v tématu Naplnění inicializovaných vlastností.
Během deserializace Newtonsoft.Json
přidá objekty do kolekce, i když vlastnost nemá žádné setter. System.Text.Json ignoruje vlastnosti, které nemají settery. Vlastní převaděče můžou tuto funkci poskytovat nebo můžete upgradovat na .NET 8, což může naplnit vlastnosti jen pro čtení.
Zásady pojmenování hadího případu
System.Text.Json obsahuje předdefinované zásady pojmenování pro případ hadů. U některých vstupů ale existují určité rozdíly Newtonsoft.Json
v chování. Následující tabulka uvádí některé z těchto rozdílů při převodu JsonNamingPolicy.SnakeCaseLower vstupu pomocí zásad.
Vstup | Newtonsoft.Json výsledek | System.Text.Json výsledek |
---|---|---|
"AB1" | "a_b1" | "ab1" |
"SHA512Managed" | "sh_a512_managed" | "sha512_managed" |
"abc123DEF456" | "abc123_de_f456" | "abc123_def456" |
"KEBAB-CASE" | "keba_b-_case" | "kebab-case" |
Jediná předdefinovaná zásada System.Text.Json pojmenování vlastností je určená pro camel case. Newtonsoft.Json
může převést názvy vlastností na písmena hada. Vlastní zásady pojmenování můžou tuto funkci poskytnout nebo upgradovat na .NET 8 nebo novější, což zahrnuje integrované zásady pojmenování hadů.
Atributy System.Runtime.Serialization
System.Runtime.Serialization atributy, jako DataContractAttributeje , DataMemberAttributea IgnoreDataMemberAttribute umožňují definovat kontrakt dat. Kontrakt dat je formální smlouva mezi službou a klientem, která abstraktivně popisuje data, která se mají vyměňovat. Kontrakt dat přesně definuje, které vlastnosti jsou serializovány pro výměnu.
System.Text.Json nemá integrovanou podporu těchto atributů. Od verze .NET 7 ale můžete k přidání podpory použít vlastní překladač typů. Ukázku najdete v tématu ZCS. DataContractResolver.
Osmičková čísla
Newtonsoft.Json
zachází s čísly s úvodní nulou jako osmičkovými čísly. System.Text.Json neumožňuje úvodní nuly, protože specifikace RFC 8259 je neumožňuje.
Zpracování chybějících členů
Pokud json, který se deserializuje, zahrnuje vlastnosti, které chybí v cílovém typu, lze nakonfigurovat tak, Newtonsoft.Json
aby vyvolaly výjimky. Ve výchozím nastavení System.Text.Json ignoruje další vlastnosti ve formátu JSON, s výjimkou případů, kdy použijete atribut [JsonExtensionData].
V .NET 8 a novějších verzích můžete nastavit předvolby, jestli chcete přeskočit nebo zakázat nenamapované vlastnosti JSON, a to jedním z následujících způsobů:
- JsonUnmappedMemberHandlingAttribute Použijte atribut na typ, na který deserializujete.
- Pokud chcete nastavit předvolby globálně, nastavte JsonSerializerOptions.UnmappedMemberHandling vlastnost. Nebo pro generování zdroje nastavte JsonSourceGenerationOptionsAttribute.UnmappedMemberHandling vlastnost a použijte atribut pro vaši JsonSerializerContext třídu.
- Přizpůsobte JsonTypeInfo.UnmappedMemberHandling vlastnost.
JsonObjectAttribute
Newtonsoft.Json
má atribut, který JsonObjectAttribute
lze použít na úrovni typu k řízení, které členy jsou serializovány, jak null
se hodnoty zpracovávají a zda jsou požadovány všechny členy. System.Text.Json nemá žádný ekvivalentní atribut, který lze použít u typu. U některých chování, jako null
je zpracování hodnot, můžete buď nakonfigurovat stejné chování na globální JsonSerializerOptions , nebo jednotlivě u každé vlastnosti.
Vezměte v úvahu následující příklad, který používá Newtonsoft.Json.JsonObjectAttribute
k určení, že všechny null
vlastnosti by měly být ignorovány:
[JsonObject(ItemNullValueHandling = NullValueHandling.Ignore)]
public class Person { ... }
V System.Text.Jsonaplikaci můžete nastavit chování pro všechny typy a vlastnosti:
JsonSerializerOptions options = new()
{
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
};
string json = JsonSerializer.Serialize<Person>(person, options);
Nebo můžete chování jednotlivých vlastností nastavit samostatně:
public class Person
{
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? Name { get; set; }
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public int? Age { get; set; }
}
Dále vezměte v úvahu následující příklad, který používá Newtonsoft.Json.JsonObjectAttribute
k určení, že všechny vlastnosti člena musí být přítomny ve formátu JSON:
[JsonObject(ItemRequired = Required.Always)]
public class Person { ... }
Stejné chování System.Text.Json můžete dosáhnout přidáním modifikátoru jazyka C# required
nebo JsonRequiredAttribute do každé vlastnosti. Další informace naleznete v tématu Povinné vlastnosti.
public class Person
{
[JsonRequired]
public string? Name { get; set; }
public required int? Age { get; set; }
}
TraceWriter
Newtonsoft.Json
umožňuje ladit pomocí protokolu TraceWriter
, které jsou generovány serializací nebo deserializací. System.Text.Json neprovádí protokolování.
JsonDocument a JsonElement ve srovnání s JTokenem (například JObject, JArray)
System.Text.Json.JsonDocument poskytuje možnost parsovat a sestavit model DOM (Document Object Model) jen pro čtení z existujících datových částí JSON. DOM poskytuje náhodný přístup k datům v datové části JSON. K elementům JSON, které tvoří datovou část, je možné přistupovat prostřednictvím JsonElement typu. Tento JsonElement
typ poskytuje rozhraní API pro převod textu JSON na běžné typy .NET. JsonDocument
RootElement zveřejňuje vlastnost.
Počínaje rozhraním .NET 6 můžete parsovat a sestavit proměnlivý dom z existujících datových částí JSON pomocí JsonNode typu a dalších typů v System.Text.Json.Nodes oboru názvů. Další informace naleznete v tématu Použití JsonNode
.
JsonDocument je IDisposable
JsonDocument
vytvoří zobrazení dat v paměti do vyrovnávací paměti ve fondu. Proto na rozdíl od JObject
, Newtonsoft.Json
JArray
JsonDocument
typ implementuje IDisposable
a je třeba použít uvnitř bloku using. Další informace najdete v tématu JsonDocument je IDisposable.
JsonDocument je jen pro čtení
DOM System.Text.Json nemůže přidávat, odebírat ani upravovat elementy JSON. Je navržený tak, aby byl výkon a snížil přidělení pro analýzu běžných velikostí datových částí JSON (to znamená < 1 MB).
JsonElement je sjednocující struktura.
JsonDocument
zpřístupňuje RootElement
jako vlastnost typu JsonElement, což je sjednocující typ struktury, který zahrnuje všechny elementy JSON. Newtonsoft.Json
používá vyhrazené hierarchické typy jako JObject
, , JToken
JArray
a tak dále. JsonElement
je to, co můžete prohledávat a vyčíslovat, a můžete použít JsonElement
k materializaci elementů JSON do typů .NET.
Počínaje rozhraním .NET 6 můžete použít JsonNode typ a typy v System.Text.Json.Nodes oboru názvů, který odpovídá JObject
, JArray
a JToken
. Další informace naleznete v tématu Použití JsonNode
.
Vyhledání dílčích elementů ve formátu JsonDocument a JsonElement
Vyhledá tokeny JSON, které používají JObject
nebo JArray
z Newtonsoft.Json
nich mají tendenci být poměrně rychlé, protože se jedná o vyhledávání v některém slovníku. Při porovnávání JsonElement
vyhledávání vyžaduje sekvenční vyhledávání vlastností, a proto jsou relativně pomalé (například při použití TryGetProperty
). System.Text.Json je navržen tak, aby minimalizoval počáteční čas analýzy místo doby vyhledávání. Další informace najdete v tématu Jak hledat v souboru JsonDocument a JsonElement dílčí prvky.
Utf8JsonReader vs. JsonTextReader
System.Text.Json.Utf8JsonReaderje vysoce výkonná, nízká alokace, čtečka jen pro čtení textu JSON s kódováním UTF-8, čtení z bajtu >ReadOnlySpan<nebo byte> ReadOnlySequence<. Jedná se Utf8JsonReader
o typ nízké úrovně, který lze použít k vytváření vlastních analyzátorů a deserializérů.
Utf8JsonReader je ref – struktura
Newtonsoft.Json
In JsonTextReader
je třída. Typ Utf8JsonReader
se liší v tom, že se jedná o strukturu odkazu. Další informace najdete v tématu omezení struktury ref pro Utf8JsonReader.
Čtení hodnot null do typů hodnot s možnou hodnotou null
Newtonsoft.Json
poskytuje rozhraní API, která vrací Nullable<T>, například ReadAsBoolean
, která za vás zpracovává Null
TokenType
vrácením .bool?
Integrovaná System.Text.Json
rozhraní API vrací pouze typy hodnot, které nemají hodnotu null. Další informace naleznete v tématu Čtení hodnot null do typů hodnot s možnou hodnotou null.
Vícecílový cíl pro čtení JSON
Pokud potřebujete pokračovat v používání Newtonsoft.Json
pro určité cílové architektury, můžete mít více cílů a mít dvě implementace. To ale není triviální a vyžadovalo by to určité #ifdefs
a zdrojové duplicity. Jedním ze způsobů, jak sdílet co nejvíce kódu, je vytvořit obálku ref struct
kolem Utf8JsonReader a Newtonsoft.Json.JsonTextReader
. Tento obálka by sjednotila veřejnou plochu při izolování rozdílů v chování. Díky tomu můžete izolovat změny hlavně ve konstrukci typu spolu s předáváním nového typu podle odkazu. Toto je vzor, který knihovna Microsoft.Extensions.DependencyModel sleduje:
Utf8JsonWriter vs. JsonTextWriter
System.Text.Json.Utf8JsonWriter je vysoce výkonný způsob, jak psát kódovaný text JSON UTF-8 z běžných typů .NET, jako je String
, Int32
a DateTime
. Zapisovač je typ nízké úrovně, který lze použít k sestavení vlastních serializátorů.
Zápis nezpracovaných hodnot
Newtonsoft.Json
má metodu, která zapisuje nezpracovaný WriteRawValue
kód JSON, kde se očekává hodnota. System.Text.Json má přímý ekvivalent: Utf8JsonWriter.WriteRawValue. Další informace najdete v tématu Zápis nezpracovaných souborů JSON.
Přizpůsobení formátu JSON
JsonTextWriter
obsahuje následující nastavení, pro která Utf8JsonWriter nemá žádný ekvivalent:
- QuoteChar – Určuje znak, který se má použít k obklopování řetězcových hodnot.
Utf8JsonWriter
vždy používá dvojité uvozovky. - QuoteName – Určuje, zda se mají názvy vlastností ohraničovaly uvozovkami.
Utf8JsonWriter
vždy je obklopuje uvozovkami.
Od verze .NET 9 můžete přizpůsobit znak a velikost odsazení pro Utf8JsonWriter použití možností vystavených strukturou JsonWriterOptions :
JsonTextWriter
obsahuje následující nastavení, pro která Utf8JsonWriter
nemá žádný ekvivalent:
- Odsazení – Určuje, kolik znaků se má odsadit.
Utf8JsonWriter
vždy odsadí o 2 znaky. - IndentChar – Určuje znak, který se má použít pro odsazení.
Utf8JsonWriter
vždy používá prázdné znaky. - QuoteChar – Určuje znak, který se má použít k obklopování řetězcových hodnot.
Utf8JsonWriter
vždy používá dvojité uvozovky. - QuoteName – Určuje, zda se mají názvy vlastností ohraničovaly uvozovkami.
Utf8JsonWriter
vždy je obklopuje uvozovkami.
Neexistují žádná alternativní řešení, která by vám umožnila přizpůsobit json vytvořený Utf8JsonWriter
těmito způsoby.
Hodnoty časového rozsahu, identifikátoru URI nebo znaku
JsonTextWriter
poskytuje WriteValue
metody pro hodnoty TimeSpan, Uri a char . Utf8JsonWriter
nemá ekvivalentní metody. Místo toho tyto hodnoty naformátovat jako řetězce (například voláním ToString()
) a voláním WriteStringValue.
Vícecílový pro zápis JSON
Pokud potřebujete pokračovat v používání Newtonsoft.Json
pro určité cílové architektury, můžete mít více cílů a mít dvě implementace. To ale není triviální a vyžadovalo by to určité #ifdefs
a zdrojové duplicity. Jedním ze způsobů, jak sdílet co nejvíce kódu, je vytvořit obálku kolem Utf8JsonWriter a Newtonsoft.Json.JsonTextWriter
. Tento obálka by sjednotila veřejnou plochu při izolování rozdílů v chování. Díky tomu můžete izolovat změny hlavně v konstrukci typu. Knihovna Microsoft.Extensions.DependencyModel :
TypeNameHandling.All se nepodporuje
Rozhodnutí vyloučit TypeNameHandling.All
z ní ekvivalentní funkce System.Text.Json
bylo záměrné. Povolení datové části JSON zadat vlastní informace o typu je běžným zdrojem ohrožení zabezpečení ve webových aplikacích. Konkrétně konfigurace Newtonsoft.Json
umožňuje TypeNameHandling.All
vzdálenému klientovi vložit celou spustitelné aplikaci do samotné datové části JSON, aby během deserializace webové aplikace extrahovala a spustila vložený kód. Další informace najdete v pátek v 13. útoku JSON na PowerPoint a pátek podrobnosti o 13. útoku JSON.
Nepodporované dotazy na cestu JSON
DOM JsonDocument
nepodporuje dotazování pomocí cesty JSON.
JsonNode V systému DOM má každá JsonNode
instance metoduGetPath
, která vrací cestu k uzlu. Neexistuje ale žádné integrované rozhraní API pro zpracování dotazů založených na řetězcích dotazu cesty JSON.
Další informace najdete v problému s dotnet/runtime #31068 Na GitHubu.
Některá omezení nelze konfigurovat.
System.Text.Json nastaví omezení, která se nedají změnit u některých hodnot, například maximální velikost tokenu ve znaky (166 MB) a v základu 64 (125 MB). Další informace najdete JsonConstants
ve zdrojovém kódu a problému s GitHubem dotnet/runtime č. 39953.
NaN, Nekonečno, -Nekonečno
Newtonsoft parsuje NaN
a Infinity
-Infinity
řetězcové tokeny JSON. S System.Text.Json, použít JsonNumberHandling.AllowNamedFloatingPointLiterals. Informace o tom, jak toto nastavení použít, najdete v tématu Povolit nebo napsat čísla v uvozovkách.
Použití GitHub Copilotu k migraci
Pomoc s kódováním můžete získat z GitHub Copilotu a převést kód v integrovaném vývojovém prostředí (IDE).
Pokud používáte Visual Studio 2022 verze 17.8 nebo novější, můžete vyzkoušet GitHub Copilot řízený pomocí AI v sadě Visual Studio a pomoct migrovat Newtonsoft.Json
kód, který se má použít System.Text.Json
. Odešlete svůj dotaz a kód, který chcete převést jako výzvu v okně chatu copilot, jako v následujícím příkladu.
Poznámka:
GitHub Copilot využívá technologii AI, takže jsou možná překvapení a chyby. Nezapomeňte ověřit vygenerovaný kód nebo návrhy. Další informace o obecném použití GitHub Copilotu, dopadu produktu, lidského dohledu a ochrany osobních údajů najdete v nejčastějších dotazech ke Kopírování GitHubu.
Příklad výzvy ke kopírování chatu
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);
Příklad odpovědi zkopírovaného chatu
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.
Všimněte si, že výsledky se můžou lišit od výsledků zobrazených v těchto ukázkových odpovědích. Modely AI nejsou deterministické, což znamená, že při kladení stejné otázky můžou vrátit různé odpovědi. Důvodem může být další učení a přizpůsobení v průběhu času, jazykové variace, změny v kontextu, například historie chatu a další.
Pomocí funkcí chatu, jako jsou příkazy lomítka, odkazy a vlákna, můžete nastavit záměr a získat lepší odpovědi s vymezeným kontextem.
Pokud je například váš soubor filename
kódu otevřený v integrovaném vývojovém prostředí( IDE), můžete na soubor odkazovat ve výzvě ke zkopírování chatu pomocí příkazu "převést #filename
na použití System.Text.Json
". Nebo můžete na řešení odkazovat příkazem "Převést @workspace
na použití System.Text.Json
" v okně chatu nebo v vloženým chatu.