Migrowanie z Newtonsoft.Json do System.Text.Json
W tym artykule pokazano, jak przeprowadzić migrację z Newtonsoft.Json programu do System.Text.Jsonprogramu .
System.Text.Json
Przestrzeń nazw zapewnia funkcje serializacji do i deserializacji z pliku JavaScript Object Notation (JSON). Biblioteka jest zawarta System.Text.Json
w środowisku uruchomieniowym platformy .NET Core 3.1 i nowszych wersjach. W przypadku innych platform docelowych zainstaluj System.Text.Json pakiet NuGet. Pakiet obsługuje:
- .NET Standard 2.0 i nowsze wersje
- .NET Framework 4.6.2 i nowsze wersje
- .NET Core 2.0, 2.1 i 2.2
Napiwek
Możesz użyć pomocy dotyczącej sztucznej inteligencji, aby przeprowadzić migrację z Newtonsoft.Json
usługi GitHub Copilot.
System.Text.Json
koncentruje się głównie na wydajności, bezpieczeństwie i zgodności ze standardami. Ma ona pewne kluczowe różnice w zachowaniu domyślnym i nie ma na celu parzystości funkcji z Newtonsoft.Json
. W przypadku niektórych scenariuszy System.Text.Json
obecnie nie ma wbudowanych funkcji, ale istnieją zalecane obejścia. W przypadku innych scenariuszy obejścia są niepraktyczne.
Zespół System.Text.Json
inwestuje w dodawanie funkcji, które są najczęściej wymagane. Jeśli aplikacja zależy od brakującej funkcji, rozważ zgłoszenie problemu w repozytorium dotnet/runtime GitHub, aby dowiedzieć się, czy można dodać obsługę danego scenariusza.
Większość tego artykułu dotyczy sposobu korzystania z interfejsu JsonSerializer API, ale zawiera również wskazówki dotyczące używania JsonDocument (który reprezentuje model obiektów dokumentów lub DOM), Utf8JsonReaderi Utf8JsonWriter typów.
W języku Visual Basic nie można użyć Utf8JsonReaderelementu , co oznacza również, że nie można pisać konwerterów niestandardowych. Większość przedstawionych tutaj obejść wymaga pisania konwerterów niestandardowych. Konwerter niestandardowy można napisać w języku C# i zarejestrować go w projekcie Języka Visual Basic. Aby uzyskać więcej informacji, zobacz Obsługa języka Visual Basic.
Tabela różnic
W poniższej tabeli wymieniono Newtonsoft.Json
funkcje i System.Text.Json
odpowiedniki. Odpowiedniki należą do następujących kategorii:
- ✔️ Obsługiwane przez wbudowane funkcje. Uzyskanie podobnego zachowania
System.Text.Json
może wymagać użycia atrybutu lub opcji globalnej. -
⚠✔ Nieobsługiwane, ale możliwe jest obejście problemu. Obejścia to konwertery niestandardowe, które mogą nie zapewniać pełnej równoważności z funkcjami
Newtonsoft.Json
. W przypadku niektórych z nich przykładowy kod jest dostarczany jako przykłady. Jeśli korzystasz z tychNewtonsoft.Json
funkcji, migracja będzie wymagać modyfikacji modeli obiektów platformy .NET lub innych zmian kodu. -
❌ Nieobsługiwane, a obejście nie jest praktyczne ani możliwe. Jeśli korzystasz z tych
Newtonsoft.Json
funkcji, migracja nie będzie możliwa bez istotnych zmian.
Funkcja systemu Newtonsoft.Json | System.Text.Json równoważny |
---|---|
Deserializacji bez uwzględniania wielkości liter domyślnie | ✔️ Ustawienie globalne WłaściwościNameCaseInsensitive |
Nazwy właściwości camel-case | ✔️ Ustawienie globalne PropertyNamingPolicy |
Nazwy właściwości Snake-case | ✔️ Zasady nazewnictwa przypadków węża |
Minimalny znak ucieczki | ✔️ Ścisłe znaki ucieczki, konfigurowalne |
NullValueHandling.Ignore ustawienie globalne |
✔️ Opcja globalna DefaultIgnoreCondition |
Zezwalaj na komentarze | ✔️ ReadCommentHandling — ustawienie globalne |
Zezwalaj na przecinki końcowe | ✔️ Ustawienie globalne AllowTrailingCommas |
Rejestracja konwertera niestandardowego | ✔️ Kolejność pierwszeństwa różni się |
Domyślna maksymalna głębokość 64, konfigurowalna | ✔️ Domyślna maksymalna głębokość 64, konfigurowalna |
PreserveReferencesHandling ustawienie globalne |
✔️ Ustawienie globalne ReferenceHandling |
Serializowanie lub deserializowanie liczb w cudzysłowie | ✔️ NumberHandling ustawienia globalnego [JsonNumberHandling] atrybut |
Deserializowanie do niezmiennych klas i struktur | ✔️ JsonConstructor, rekordy języka C# 9 |
Obsługa pól | ✔️ Ustawienie globalne IncludeFields, atrybut [JsonInclude] |
DefaultValueHandling ustawienie globalne |
✔️ Ustawienie globalne DefaultIgnoreCondition |
NullValueHandling ustawienie włączone [JsonProperty] |
✔️ Atrybut JsonIgnore |
DefaultValueHandling ustawienie włączone [JsonProperty] |
✔️ Atrybut JsonIgnore |
Deserializowanie Dictionary przy użyciu klucza innego niż ciąg |
✔️ Obsługiwane |
Obsługa zestawów właściwości innych niż publiczne i metody pobierania | ✔️ Atrybut JsonInclude |
Atrybut [JsonConstructor] |
✔️ [JsonConstructor] , atrybut |
ReferenceLoopHandling ustawienie globalne |
✔️ Ustawienie globalne ReferenceHandling |
Wywołania zwrotne | ✔️ Wywołania zwrotne |
NaN, Infinity, -Infinity | ✔️ Obsługiwane |
Required ustawienie atrybutu [JsonProperty] |
✔️ [JsonRequired] atrybut i wymagany modyfikator języka C# |
DefaultContractResolver aby zignorować właściwości |
✔️ DefaultJsonTypeInfoResolver, klasa |
Serializacja polimorficzna | ✔️ [JsonDerivedType] , atrybut |
Deserializacja polimorficzna | ✔️ Dyskryminujący typ atrybutu [JsonDerivedType] |
Deserializowanie wartości wyliczenia ciągów | ✔️ Deserializowanie wartości wyliczenia ciągów |
MissingMemberHandling ustawienie globalne |
✔️ Obsługa brakujących elementów członkowskich |
Wypełnianie właściwości bez ustawiających | ✔️ Wypełnianie właściwości bez ustawiających |
ObjectCreationHandling ustawienie globalne |
✔️ Ponowne użycie, a nie zastępowanie właściwości |
Obsługa szerokiego zakresu typów | ⚠✔ Niektóre typy wymagają konwerterów niestandardowych |
Deserializowanie wnioskowania typu do object właściwości |
⚠✔ Nieobsługiwane, obejście, przykład |
Deserializowanie literału JSON null do typów wartości innych niż null |
⚠✔ Nieobsługiwane, obejście, przykład |
DateTimeZoneHandling , DateFormatString ustawienia |
⚠✔ Nieobsługiwane, obejście, przykład |
JsonConvert.PopulateObject metoda |
⚠✔ Nieobsługiwane, obejście |
Obsługa System.Runtime.Serialization atrybutów |
⚠✔ Nieobsługiwane, obejście, przykład |
JsonObjectAttribute |
⚠✔ Nieobsługiwane, obejście |
Zezwalaj na nazwy właściwości bez cudzysłowów | ❌ Nieobsługiwane przez projekt |
Zezwalaj na pojedyncze cudzysłowy wokół wartości ciągu | ❌ Nieobsługiwane przez projekt |
Zezwalaj na wartości JSON innych niż ciąg dla właściwości ciągu | ❌ Nieobsługiwane przez projekt |
TypeNameHandling.All ustawienie globalne |
❌ Nieobsługiwane przez projekt |
Obsługa JsonPath zapytań |
❌ Nieobsługiwane |
Konfigurowalne limity | ❌ Nieobsługiwane |
Nie jest to wyczerpująca lista Newtonsoft.Json
funkcji. Lista zawiera wiele scenariuszy, które zostały żądane w problemach z usługą GitHub lub wpisami StackOverflow . Jeśli zaimplementujesz obejście jednego ze scenariuszy wymienionych w tym miejscu, które nie ma obecnie przykładowego kodu, a jeśli chcesz udostępnić rozwiązanie, wybierz tę stronę w sekcji Opinie w dolnej części tej strony. Spowoduje to utworzenie problemu w repozytorium GitHub tej dokumentacji i wyświetlenie go również w sekcji Opinie na tej stronie.
Różnice w zachowaniu domyślnym
System.Text.Json jest domyślnie rygorystyczny i unika odgadywania lub interpretacji w imieniu wywołującego, podkreślając deterministyczne zachowanie. Biblioteka została celowo zaprojektowana w ten sposób pod kątem wydajności i zabezpieczeń.
Newtonsoft.Json
jest domyślnie elastyczny. Ta podstawowa różnica w projekcie stoi za wieloma z następujących specyficznych różnic w zachowaniu domyślnym.
Deserializacji bez uwzględniania wielkości liter
Podczas deserializacji Newtonsoft.Json
domyślnie jest dopasowywana nazwa właściwości bez uwzględniania wielkości liter. Wartość domyślna System.Text.Json jest uwzględniana w wielkości liter, co zapewnia lepszą wydajność, ponieważ wykonuje dokładne dopasowanie. Aby uzyskać informacje na temat dopasowywania bez uwzględniania wielkości liter, zobacz Dopasowywanie właściwości bez uwzględniania wielkości liter.
Jeśli używasz System.Text.Json
pośrednio przy użyciu ASP.NET Core, nie musisz wykonywać żadnych czynności, aby uzyskać zachowanie takie jak Newtonsoft.Json
. ASP.NET Core określa ustawienia nazw właściwości wielbłądowych i dopasowywania bez uwzględniania wielkości liter, gdy używa System.Text.Json
.
ASP.NET Core umożliwia również deserializowanie liczb cytowanych domyślnie.
Minimalny znak ucieczki
Podczas serializacji Newtonsoft.Json
, jest stosunkowo permissive o puszczanie znaków bez ucieczki. Oznacza to, że nie zastępuje ich \uxxxx
miejscem, w którym xxxx
jest punkt kodu znaku. W przypadku ich ucieczki, robi to przez emitowanie znaku przed znakiem \
(na przykład "
staje się \"
).
System.Text.Json domyślnie zapewnia ochronę przed atakami skryptowymi między witrynami (XSS) lub atakami polegającymi na ujawnianiu informacji, a także za pomocą sekwencji sześciu znaków.
System.Text.Json
domyślnie nie ma żadnych znaków innych niż ASCII, więc nie musisz wykonywać żadnych czynności, jeśli używasz StringEscapeHandling.EscapeNonAscii
polecenia w systemie Newtonsoft.Json
.
System.Text.Json
domyślnie jest również chroniony znakami wrażliwymi na kod HTML. Aby uzyskać informacje na temat zastępowania zachowania domyślnego System.Text.Json
, zobacz Dostosowywanie kodowania znaków.
Komentarze
Podczas deserializacji Newtonsoft.Json
domyślnie ignoruje komentarze w formacie JSON. Wartością domyślną System.Text.Json jest zgłaszanie wyjątków dla komentarzy, ponieważ specyfikacja RFC 8259 nie zawiera ich. Aby uzyskać informacje o sposobie zezwalania na komentarze, zobacz Zezwalaj na komentarze i końcowe przecinki.
Przecinki końcowe
Podczas deserializacji Newtonsoft.Json
domyślnie ignoruje końcowe przecinki. Ignoruje również wiele przecinków końcowych (na przykład [{"Color":"Red"},{"Color":"Green"},,]
). Wartością domyślną System.Text.Json jest zgłaszanie wyjątków dla przecinków końcowych, ponieważ specyfikacja RFC 8259 nie zezwala na nie. Aby uzyskać informacje na temat sposobu System.Text.Json
ich akceptowania, zobacz Zezwalaj na komentarze i końcowe przecinki. Nie ma możliwości zezwalania na wiele przecinków końcowych.
Pierwszeństwo rejestracji konwertera
Pierwszeństwo Newtonsoft.Json
rejestracji dla konwerterów niestandardowych jest następujące:
- Atrybut we właściwości
- Atrybut w typie
- Kolekcja konwerterów
Ta kolejność oznacza, że konwerter niestandardowy w Converters
kolekcji jest zastępowany przez konwerter zarejestrowany przez zastosowanie atrybutu na poziomie typu. Obie te rejestracje są zastępowane przez atrybut na poziomie właściwości.
Pierwszeństwo System.Text.Json rejestracji dla konwerterów niestandardowych różni się:
- Atrybut we właściwości
- Converters kolekcja
- Atrybut w typie
Różnica polega na tym, że konwerter niestandardowy w Converters
kolekcji zastępuje atrybut na poziomie typu. Celem tego porządku pierwszeństwa jest wprowadzenie zmian w czasie wykonywania zastąpić opcje czasu projektowania. Nie ma możliwości zmiany pierwszeństwa.
Aby uzyskać więcej informacji na temat rejestracji konwertera niestandardowego, zobacz Rejestrowanie konwertera niestandardowego.
Maksymalna głębokość
Najnowsza wersja programu Newtonsoft.Json
ma domyślnie maksymalny limit głębokości wynoszący 64.
System.Text.Json Ma również domyślny limit 64 i można go skonfigurować, ustawiając wartość JsonSerializerOptions.MaxDepth.
Jeśli używasz System.Text.Json
pośrednio przy użyciu ASP.NET Core, domyślny maksymalny limit głębokości wynosi 32. Wartość domyślna jest taka sama jak w przypadku powiązania modelu i jest ustawiona w klasie JsonOptions.
Ciągi JSON (nazwy właściwości i wartości ciągów)
Podczas deserializacji Newtonsoft.Json
akceptuje nazwy właściwości otoczone podwójnymi cudzysłowami, apostrofami lub bez cudzysłowów. Akceptuje wartości ciągów otoczone podwójnymi cudzysłowami lub pojedynczymi cudzysłowami. Na przykład Newtonsoft.Json
akceptuje następujący kod JSON:
{
"name1": "value",
'name2': "value",
name3: 'value'
}
System.Text.Json
Akceptuje tylko nazwy właściwości i wartości ciągów w cudzysłowach, ponieważ ten format jest wymagany przez specyfikację RFC 8259 i jest jedynym formatem uznawanym za prawidłowy kod JSON.
Wartość ujęta w pojedynczy cudzysłów powoduje wyjątek JsonException z następującym komunikatem:
''' is an invalid start of a value.
Wartości inne niż ciągi dla właściwości ciągu
Newtonsoft.Json
akceptuje wartości inne niż ciągi, takie jak liczba lub literały true
i false
, do deserializacji właściwości typu ciąg. Oto przykładowy kod JSON, który Newtonsoft.Json
pomyślnie deserializuje do następującej klasy:
{
"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
nie deserializuje wartości innych niż ciągi we właściwościach ciągu. Odebrana wartość nieciągniowa dla pola ciągu powoduje wyjątek JsonException z następującym komunikatem:
The JSON value could not be converted to System.String.
Scenariusze korzystające z narzędzia JsonSerializer
Niektóre z poniższych scenariuszy nie są obsługiwane przez wbudowane funkcje, ale możliwe są obejścia. Obejścia to konwertery niestandardowe, które mogą nie zapewniać pełnej równoważności z funkcjami Newtonsoft.Json
. W przypadku niektórych z nich przykładowy kod jest dostarczany jako przykłady. Jeśli korzystasz z tych Newtonsoft.Json
funkcji, migracja będzie wymagać modyfikacji modeli obiektów platformy .NET lub innych zmian kodu.
W przypadku niektórych z poniższych scenariuszy obejścia nie są praktyczne ani możliwe. Jeśli korzystasz z tych Newtonsoft.Json
funkcji, migracja nie będzie możliwa bez istotnych zmian.
Zezwalaj na liczby w cudzysłowie lub zapisuj je
Newtonsoft.Json
może serializować lub deserializować liczby reprezentowane przez ciągi JSON (otoczone cudzysłowami). Na przykład może zaakceptować: {"DegreesCelsius":"23"}
zamiast {"DegreesCelsius":23}
. Aby włączyć to zachowanie w systemie System.Text.Json, ustaw JsonSerializerOptions.NumberHandling na WriteAsString lub AllowReadingFromString, lub użyj atrybutu [JsonNumberHandling].
Jeśli używasz System.Text.Json
pośrednio przy użyciu ASP.NET Core, nie musisz wykonywać żadnych czynności, aby uzyskać zachowanie takie jak Newtonsoft.Json
. ASP.NET Core określa wartości domyślne sieci Web, gdy używa System.Text.Json
wartości , a wartości domyślne sieci Web zezwalają na liczby cytowane.
Aby uzyskać więcej informacji, zobacz Zezwalanie na liczby w cudzysłowie lub zapisywanie ich w cudzysłowie.
Określanie konstruktora do użycia podczas deserializacji
Atrybut Newtonsoft.Json
[JsonConstructor]
umożliwia określenie konstruktora do wywołania podczas deserializacji do klasy POCO.
System.Text.Json
ma również atrybut [JsonConstructor]. Aby uzyskać więcej informacji, zobacz Niezmienne typy i rekordy.
Warunkowe ignorowanie właściwości
Newtonsoft.Json
Program ma kilka sposobów warunkowego ignorowania właściwości serializacji lub deserializacji:
-
DefaultContractResolver
Umożliwia wybranie właściwości do uwzględnienia lub zignorowania na podstawie dowolnych kryteriów. - Ustawienia
NullValueHandling
iDefaultValueHandling
JsonSerializerSettings
umożliwiają określenie, że wszystkie właściwości null-value lub default-value powinny być ignorowane. - Ustawienia
NullValueHandling
iDefaultValueHandling
w atrybucie[JsonProperty]
umożliwiają określenie poszczególnych właściwości, które powinny być ignorowane po ustawieniu wartości null lub wartości domyślnej.
System.Text.Json Udostępnia następujące sposoby ignorowania właściwości lub pól podczas serializacji:
- Atrybut [JsonIgnore] we właściwości powoduje pominięcie właściwości z formatu JSON podczas serializacji.
- Opcja globalna IgnoreReadOnlyProperties umożliwia ignorowanie wszystkich właściwości tylko do odczytu.
- Jeśli dołączasz pola, JsonSerializerOptions.IgnoreReadOnlyFields opcja globalna umożliwia ignorowanie wszystkich pól tylko do odczytu.
- Opcja
DefaultIgnoreCondition
globalna umożliwia ignorowanie wszystkich właściwości typu wartości, które mają wartości domyślne, lub ignorowanie wszystkich właściwości typu odwołania, które mają wartości null.
Ponadto w wersjach .NET 7 i nowszych można dostosować kontrakt JSON, aby ignorować właściwości na podstawie dowolnych kryteriów. Aby uzyskać więcej informacji, zobacz Kontrakty niestandardowe.
Pola publiczne i inne niż publiczne
Newtonsoft.Json
może serializować i deserializować pola, a także właściwości.
W System.Text.Jsonsystemie użyj ustawienia globalnego JsonSerializerOptions.IncludeFields lub atrybutu [JsonInclude], aby uwzględnić pola publiczne podczas serializacji lub deserializacji. Aby zapoznać się z przykładem, zobacz Dołączanie pól.
Zachowywanie odwołań do obiektów i pętle obsługi
Domyślnie Newtonsoft.Json
serializuje według wartości. Jeśli na przykład obiekt zawiera dwie właściwości, które zawierają odwołanie do tego samego Person
obiektu, wartości właściwości tego Person
obiektu są zduplikowane w formacie JSON.
Newtonsoft.Json
PreserveReferencesHandling
ma ustawienie, JsonSerializerSettings
które umożliwia serializację według odwołania:
- Metadane identyfikatora są dodawane do pliku JSON utworzonego dla pierwszego
Person
obiektu. - Kod JSON utworzony dla drugiego
Person
obiektu zawiera odwołanie do tego identyfikatora zamiast wartości właściwości.
Newtonsoft.Json
Ma ReferenceLoopHandling
również ustawienie, które pozwala ignorować odwołania cykliczne, a nie zgłaszać wyjątku.
Aby zachować odwołania i obsłużyć odwołania cykliczne w elemencie System.Text.Json, ustaw wartość JsonSerializerOptions.ReferenceHandlerPreserve. To ustawienie jest równoważne w elemencie ReferenceHandler.Preserve
PreserveReferencesHandling
= PreserveReferencesHandling.All
Newtonsoft.Json
.
Opcja ReferenceHandler.IgnoreCycles
ma zachowanie podobne do Newtonsoft.JsonReferenceLoopHandling.Ignore
. Jedną z różnic jest to, że implementacja System.Text.Json zastępuje pętle odwołań tokenem null
JSON zamiast ignorować odwołanie do obiektu. Aby uzyskać więcej informacji, zobacz Ignoruj odwołania cykliczne.
Podobnie jak w przypadku Newtonsoft.Jsonklasy ReferenceResolver, System.Text.Json.Serialization.ReferenceResolver klasa definiuje zachowanie zachowania odwołań do serializacji i deserializacji. Utwórz klasę pochodną, aby określić zachowanie niestandardowe. Aby zapoznać się z przykładem, zobacz GuidReferenceResolver.
Niektóre powiązane Newtonsoft.Json
funkcje nie są obsługiwane:
Aby uzyskać więcej informacji, zobacz Zachowywanie odwołań i obsługa odwołań cyklicznych.
Słownik z kluczem nieciągowym
Zarówno kolekcje, jak Newtonsoft.Json
i System.Text.Json
obsługują kolekcje typu Dictionary<TKey, TValue>
. Aby uzyskać informacje o obsługiwanych typach kluczy, zobacz Obsługiwane typy kluczy.
Uwaga
Deserializowanie w Dictionary<TKey, TValue>
miejscu, w którym TKey
jest wpisywane jako inne niż string
może spowodować wprowadzenie luki w zabezpieczeniach w aplikacji zużywanej. Aby uzyskać więcej informacji, zobacz dotnet/runtime#4761.
Typy bez wbudowanej obsługi
System.Text.Json nie zapewnia wbudowanej obsługi następujących typów:
- DataTable i powiązane typy (aby uzyskać więcej informacji, zobacz Obsługiwane typy)
- ExpandoObject
- TimeZoneInfo
- BigInteger
- DBNull
- Type
- ValueTuple i skojarzone z nimi typy ogólne
Konwertery niestandardowe można zaimplementować dla typów, które nie mają wbudowanej obsługi.
Serializacja polimorficzna
Newtonsoft.Json
program automatycznie wykonuje serializacji polimorficznej. Począwszy od platformy .NET 7, System.Text.Json obsługuje serializacji polimorficznej za pomocą atrybutu JsonDerivedTypeAttribute . Aby uzyskać więcej informacji, zobacz Serializowanie właściwości klas pochodnych.
Deserializacja polimorficzna
Newtonsoft.Json
TypeNameHandling
Ma ustawienie, które dodaje metadane nazwy typu do formatu JSON podczas serializacji. Używa metadanych podczas deserializacji do deserializacji polimorficznej. Począwszy od platformy .NET 7, System.Text.Json opiera się na dyskryminujących informacjach o typie w celu przeprowadzenia deserializacji polimorficznej. Te metadane są emitowane w formacie JSON, a następnie używane podczas deserializacji w celu określenia, czy deserializować typ podstawowy, czy typ pochodny. Aby uzyskać więcej informacji, zobacz Serializowanie właściwości klas pochodnych.
Aby zapewnić obsługę deserializacji polimorficznej w starszych wersjach platformy .NET, utwórz konwerter podobny do przykładu w temacie How to write custom converters (Jak pisać konwertery niestandardowe).
Deserializowanie wartości wyliczenia ciągów
Domyślnie System.Text.Json nie obsługuje deserializacji wartości wyliczenia ciągów, natomiast Newtonsoft.Json
nie. Na przykład następujący kod zgłasza błąd 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
}
Można jednak włączyć deserializacji wartości wyliczenia ciągów przy użyciu konwertera JsonStringEnumConverter . Aby uzyskać więcej informacji, zobacz wyliczenia jako ciągi.
Deserializacja właściwości obiektu
Gdy Newtonsoft.Json
deserializuje wartość Object, to:
- Wywnioskuje typ wartości pierwotnych w ładunku JSON (innym niż
null
) i zwraca przechowywanystring
obiekt , ,long
double
,boolean
lubDateTime
jako obiekt w polu. Wartości pierwotne to pojedyncze wartości JSON, takie jak liczba JSON, ciąg,true
,false
lubnull
. - Zwraca wartość
JObject
lubJArray
dla wartości złożonych w ładunku JSON. Wartości złożone to kolekcje par klucz-wartość JSON w nawiasach klamrowych ({}
) lub listach wartości w nawiasach kwadratowych ([]
). Właściwości i wartości w nawiasach klamrowych lub nawiasach mogą mieć dodatkowe właściwości lub wartości. - Zwraca odwołanie o wartości null, gdy ładunek ma
null
literał JSON.
System.Text.Json przechowuje pola JsonElement
zarówno dla wartości pierwotnych, jak i złożonych przy każdym deserializacji do Object, na przykład:
- Właściwość
object
. - Wartość słownika
object
. -
object
Wartość tablicy. - Katalog główny
object
.
Jednak traktuje System.Text.Json
to samo, co null
i zwraca odwołanie o wartości null, Newtonsoft.Json
gdy ładunek ma null
literał JSON w nim.
Aby zaimplementować wnioskowanie typu dla object
właściwości, utwórz konwerter podobny do przykładu w temacie How to write custom converters (Jak pisać konwertery niestandardowe).
Deserializowanie wartości null do typu niepustego
Newtonsoft.Json
Nie zgłasza wyjątku w następującym scenariuszu:
-
NullValueHandling
jest ustawiona naIgnore
, i - Podczas deserializacji kod JSON zawiera wartość null dla typu wartości innej niż null.
W tym samym scenariuszu System.Text.Json zgłasza wyjątek. (Odpowiednie ustawienie obsługi wartości null w pliku System.Text.Json
to JsonSerializerOptions.IgnoreNullValues = true
.)
Jeśli jesteś właścicielem typu docelowego, najlepszym obejściem jest, aby właściwość, o której mowa, dopuszczała wartość null (na przykład zmień wartość int
na int?
).
Innym obejściem jest utworzenie konwertera dla typu, takiego jak poniższy przykład, który obsługuje wartości null dla DateTimeOffset
typów:
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);
}
}
Zarejestruj ten konwerter niestandardowy przy użyciu atrybutu we właściwości lub dodając konwerter do Converters kolekcji.
Uwaga: Powyższy konwerter obsługuje wartości null inaczej niż Newtonsoft.Json
w przypadku obiektów POCO określających wartości domyślne. Załóżmy na przykład, że następujący kod reprezentuje obiekt docelowy:
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; }
}
Załóżmy, że następujący kod JSON jest deserializowany przy użyciu powyższego konwertera:
{
"Date": null,
"TemperatureCelsius": 25,
"Summary": null
}
Po deserializacji Date
właściwość ma wartość 1/1/0001 (default(DateTimeOffset)
), czyli wartość ustawioną w konstruktorze jest zastępowana. Biorąc pod uwagę te same wartości POCO i JSON, Newtonsoft.Json
deserializacja pozostawiłaby wartość 1/1/2001 we Date
właściwości .
Deserializowanie do niezmiennych klas i struktur
Newtonsoft.Json
program może wykonać deserializacji do niezmiennych klas i struktur, ponieważ może używać konstruktorów, które mają parametry.
W System.Text.Jsonpliku użyj atrybutu [JsonConstructor], aby określić użycie konstruktora sparametryzowanego. Rekordy w języku C# 9 są również niezmienne i są obsługiwane jako cele deserializacji. Aby uzyskać więcej informacji, zobacz Niezmienne typy i rekordy.
Wymagane właściwości
W Newtonsoft.Json
pliku należy określić, że właściwość jest wymagana przez ustawienie Required
atrybutu [JsonProperty]
.
Newtonsoft.Json
zgłasza wyjątek, jeśli w formacie JSON nie zostanie odebrana żadna wartość dla właściwości oznaczonej jako wymagana.
Począwszy od platformy .NET 7, można użyć modyfikatora języka C# required
lub atrybutu JsonRequiredAttribute w wymaganej właściwości.
System.Text.Json zgłasza wyjątek, jeśli ładunek JSON nie zawiera wartości dla oznaczonej właściwości. Aby uzyskać więcej informacji, zobacz Wymagane właściwości.
Określanie formatu daty
Newtonsoft.Json
Udostępnia kilka sposobów kontrolowania DateTime
sposobu serializacji i deserializacji właściwości i DateTimeOffset
typów:
- Ustawienie
DateTimeZoneHandling
może służyć do serializacji wszystkichDateTime
wartości jako dat UTC. - Ustawienie
DateFormatString
iDateTime
konwertery mogą służyć do dostosowywania formatu ciągów daty.
System.Text.Json obsługuje standard ISO 8601-1:2019, w tym profil RFC 3339. Ten format jest powszechnie stosowany, jednoznaczny i precyzyjnie wykonuje rundy. Aby użyć dowolnego innego formatu, utwórz konwerter niestandardowy. Na przykład następujące konwertery serializują i deserializują kod JSON, który używa formatu epoki Unix z przesunięciem strefy czasowej lub bez tego przesunięcia (wartości, takie jak /Date(1590863400000-0700)/
lub /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);
}
}
Aby uzyskać więcej informacji, zobacz Obsługa funkcji DateTime i DateTimeOffset w systemie System.Text.Json.
Wywołania zwrotne
Newtonsoft.Json
umożliwia wykonywanie kodu niestandardowego w kilku punktach w procesie serializacji lub deserializacji:
- OnDeserializing (gdy zaczyna się deserializować obiekt)
- OnDeserialized (po zakończeniu deserializacji obiektu)
- OnSerializing (gdy rozpoczyna się serializowanie obiektu)
- OnSerialized (po zakończeniu serializacji obiektu)
System.Text.Json uwidacznia te same powiadomienia podczas serializacji i deserializacji. Aby ich używać, zaimplementuj co najmniej jeden z następujących interfejsów z System.Text.Json.Serialization przestrzeni nazw:
Oto przykład, który sprawdza właściwość null i zapisuje komunikaty na początku i na końcu serializacji i deserializacji:
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=
Kod OnDeserializing
nie ma dostępu do nowego wystąpienia POCO. Aby manipulować nowym wystąpieniem POCO na początku deserializacji, umieść ten kod w konstruktorze POCO.
Metody ustawiania i pobierania właściwości innych niż publiczne
Newtonsoft.Json
może używać prywatnych i wewnętrznych modułów ustawiających i pobierających za pośrednictwem atrybutu JsonProperty
.
System.Text.JsonObsługuje moduły ustawiania właściwości prywatnych i wewnętrznych oraz metody pobierania za pośrednictwem atrybutu [JsonInclude]. Aby uzyskać przykładowy kod, zobacz Metody dostępu do właściwości innych niż publiczne.
Wypełnianie istniejących obiektów
Metoda JsonConvert.PopulateObject
w Newtonsoft.Json
deserializuje dokument JSON do istniejącego wystąpienia klasy, zamiast tworzyć nowe wystąpienie.
System.Text.Json zawsze tworzy nowe wystąpienie typu docelowego przy użyciu domyślnego publicznego konstruktora bez parametrów. Konwertery niestandardowe mogą deserializacji do istniejącego wystąpienia.
Ponowne użycie, a nie zastępowanie właściwości
Począwszy od platformy .NET 8, System.Text.Json obsługuje ponowne uzyskiwanie zainicjowanych właściwości, a nie ich zastępowanie. Istnieją pewne różnice w zachowaniu, które można przeczytać w propozycji interfejsu API.
Aby uzyskać więcej informacji, zobacz Wypełnianie zainicjowanych właściwości.
Wypełnianie właściwości bez ustawiających
Począwszy od platformy .NET 8, System.Text.Json obsługuje wypełnianie właściwości, w tym te, które nie mają zestawu. Aby uzyskać więcej informacji, zobacz Wypełnianie zainicjowanych właściwości.
Zasady nazewnictwa przypadków węża
System.Text.Json zawiera wbudowane zasady nazewnictwa dla przypadku węża. Istnieją jednak pewne różnice Newtonsoft.Json
w zachowaniu dla niektórych danych wejściowych. W poniższej tabeli przedstawiono niektóre z tych różnic podczas konwertowania danych wejściowych przy użyciu JsonNamingPolicy.SnakeCaseLower zasad.
Dane wejściowe | Newtonsoft.Json wynik | System.Text.Json wynik |
---|---|---|
"AB1" | "a_b1" | "ab1" |
"SHA512Managed" | "sh_a512_managed" | "sha512_managed" |
"abc123DEF456" | "abc123_de_f456" | "abc123_def456" |
"KEBAB-CASE" | "keba_b-_case" | "kebab-case" |
Atrybuty System.Runtime.Serialization
System.Runtime.Serializationatrybuty, takie jak DataContractAttribute, DataMemberAttributei IgnoreDataMemberAttribute umożliwiają zdefiniowanie kontraktu danych. Kontrakt danych to formalna umowa między usługą a klientem, który abstrakcyjnie opisuje dane do wymiany. Kontrakt danych dokładnie definiuje, które właściwości są serializowane do wymiany.
System.Text.Json nie ma wbudowanej obsługi tych atrybutów. Jednak począwszy od platformy .NET 7, można użyć niestandardowego rozpoznawania typów w celu dodania obsługi. Aby zapoznać się z przykładem, zobacz ZCS. DataContractResolver.
Liczby ósemkowe
Newtonsoft.Json
traktuje liczby z zerem wiodącym jako liczby ósemkowe.
System.Text.Json nie zezwala na zera wiodące, ponieważ specyfikacja RFC 8259 nie zezwala na nie.
Obsługa brakujących elementów członkowskich
Jeśli plik JSON, który jest deserializowany, zawiera właściwości, których brakuje w typie docelowym, można skonfigurować tak, Newtonsoft.Json
aby zgłaszać wyjątki. Domyślnie System.Text.Json ignoruje dodatkowe właściwości w formacie JSON, z wyjątkiem użycia atrybutu [JsonExtensionData].
W programie .NET 8 lub nowszym można ustawić preferencje dotyczące tego, czy pominąć lub uniemożliwić niezamapowane właściwości JSON przy użyciu jednej z następujących metod:
- JsonUnmappedMemberHandlingAttribute Zastosuj atrybut do typu, do którego deserializujesz.
- Aby ustawić preferencje globalnie, ustaw JsonSerializerOptions.UnmappedMemberHandling właściwość . Lub w przypadku generowania JsonSourceGenerationOptionsAttribute.UnmappedMemberHandling źródła ustaw właściwość i zastosuj atrybut do JsonSerializerContext klasy.
- JsonTypeInfo.UnmappedMemberHandling Dostosuj właściwość .
JsonObjectAttribute
Newtonsoft.Json
ma atrybut , JsonObjectAttribute
który można zastosować na poziomie typu, aby kontrolować, które elementy członkowskie są serializowane, jak null
są obsługiwane wartości i czy wszystkie elementy członkowskie są wymagane.
System.Text.Json nie ma równoważnego atrybutu, który można zastosować w typie. W przypadku niektórych zachowań, takich jak null
obsługa wartości, można skonfigurować to samo zachowanie na poziomie globalnym JsonSerializerOptions lub indywidualnie dla każdej właściwości.
Rozważmy następujący przykład, który używa Newtonsoft.Json.JsonObjectAttribute
metody , aby określić, że wszystkie null
właściwości powinny być ignorowane:
[JsonObject(ItemNullValueHandling = NullValueHandling.Ignore)]
public class Person { ... }
W System.Text.Jsonprogramie można ustawić zachowanie dla wszystkich typów i właściwości:
JsonSerializerOptions options = new()
{
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
};
string json = JsonSerializer.Serialize<Person>(person, options);
Możesz też ustawić zachowanie dla każdej właściwości oddzielnie:
public class Person
{
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? Name { get; set; }
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public int? Age { get; set; }
}
Następnie rozważmy następujący przykład, który używa Newtonsoft.Json.JsonObjectAttribute
polecenia , aby określić, że wszystkie właściwości składowych muszą być obecne w formacie JSON:
[JsonObject(ItemRequired = Required.Always)]
public class Person { ... }
To samo zachowanie System.Text.Json można osiągnąć, dodając modyfikator języka C# required
lub do JsonRequiredAttributekażdej właściwości. Aby uzyskać więcej informacji, zobacz Wymagane właściwości.
public class Person
{
[JsonRequired]
public string? Name { get; set; }
public required int? Age { get; set; }
}
TraceWriter
Newtonsoft.Json
umożliwia debugowanie przy użyciu elementu , TraceWriter
aby wyświetlić dzienniki generowane przez serializacji lub deserializacji.
System.Text.Json nie wykonuje rejestrowania.
JsonDocument i JsonElement w porównaniu do JToken (na przykład JObject, JArray)
System.Text.Json.JsonDocument Umożliwia analizowanie i tworzenie modelu obiektów dokumentów tylko do odczytu (DOM) z istniejących ładunków JSON. Dom zapewnia losowy dostęp do danych w ładunku JSON. Dostęp do elementów JSON, które tworzą ładunek, można uzyskać za pośrednictwem JsonElement typu . Typ JsonElement
udostępnia interfejsy API do konwertowania tekstu JSON na typowe typy platformy .NET.
JsonDocument
uwidacznia RootElement właściwość.
Począwszy od platformy .NET 6, można przeanalizować i skompilować modyfikowalny dom z istniejących ładunków JSON przy użyciu JsonNode typu i innych typów w System.Text.Json.Nodes przestrzeni nazw. Aby uzyskać więcej informacji, zobacz Use JsonNode
.
JsonDocument to IDisposable
JsonDocument
tworzy widok danych w pamięci w buforze w puli. W związku z JObject
JArray
tym, w przeciwieństwie do Newtonsoft.Json
metody , JsonDocument
typ implementuje IDisposable
i musi być używany wewnątrz bloku using. Aby uzyskać więcej informacji, zobacz JsonDocument is IDisposable (Dokument JsonDocument to IDisposable).
Dokument JsonDocument jest tylko do odczytu
Dom System.Text.Json nie może dodawać, usuwać ani modyfikować elementów JSON. Został zaprojektowany w ten sposób pod kątem wydajności i zmniejszenia alokacji na potrzeby analizowania typowych rozmiarów ładunków JSON (czyli < 1 MB).
JsonElement to struktura unii
JsonDocument
Uwidacznia RootElement
jako właściwość typu JsonElement, która jest typem struktury unii, który obejmuje dowolny element JSON.
Newtonsoft.Json
używa dedykowanych typów hierarchicznych, takich jak JObject
, JArray
, JToken
i tak dalej.
JsonElement
to, co można wyszukiwać i wyliczać, i można użyć JsonElement
do materializowania elementów JSON w typach platformy .NET.
Począwszy od platformy .NET 6, można użyć JsonNode typów i typów w przestrzeni nazw odpowiadającej System.Text.Json.Nodes elementom JObject
, JArray
i JToken
. Aby uzyskać więcej informacji, zobacz Use JsonNode
.
Jak wyszukiwać elementy podrzędne JsonDocument i JsonElement
Wyszukuje tokeny JSON używające JObject
lub JArray
z Newtonsoft.Json
nich zwykle są stosunkowo szybkie, ponieważ są one wyszukiwane w pewnym słowniku. Dla porównania wyszukiwanie JsonElement
wymaga sekwencyjnego wyszukiwania właściwości i dlatego jest stosunkowo powolne (na przykład w przypadku używania metody TryGetProperty
).
System.Text.Json program został zaprojektowany tak, aby zminimalizować czas analizy początkowej, a nie czas wyszukiwania. Aby uzyskać więcej informacji, zobacz How to search a JsonDocument and JsonElement for sub-elements (Jak wyszukiwać elementy podrzędne JsonDocument i JsonElement).
Utf8JsonReader a JsonTextReader
System.Text.Json.Utf8JsonReaderto wysokowydajny, niski przydział, czytnik tylko do przodu dla tekstu JSON zakodowanego w formacie UTF-8, odczytywany z bajtu <>ReadOnlySpanlub ReadOnlySequence<bajtu.> Jest Utf8JsonReader
to typ niskiego poziomu, który może służyć do tworzenia niestandardowych parserów i deserializatorów.
Utf8JsonReader to struktura ref
Element JsonTextReader
in Newtonsoft.Json
jest klasą. Typ Utf8JsonReader
różni się w tym, że jest to struktura ref. Aby uzyskać więcej informacji, zobacz ograniczenia struktury ref dla utf8JsonReader.
Odczytywanie wartości null do typów wartości dopuszczanych do wartości null
Newtonsoft.Json
Udostępnia interfejsy API, które zwracają Nullable<T>element , na przykład ReadAsBoolean
, który obsługuje Null
TokenType
element za Ciebie, zwracając element bool?
. Wbudowane System.Text.Json
interfejsy API zwracają tylko typy wartości innych niż null. Aby uzyskać więcej informacji, zobacz Odczyt wartości null do typów wartości dopuszczanych do wartości null.
Wiele obiektów docelowych do odczytywania kodu JSON
Jeśli musisz nadal korzystać Newtonsoft.Json
z niektórych platform docelowych, możesz mieć wiele implementacji i mieć dwie implementacje. Nie jest to jednak proste i wymagałoby duplikowania niektórych #ifdefs
i źródłowych. Jednym ze sposobów udostępniania jak największej ref struct
ilości kodu jest utworzenie otoki wokół Utf8JsonReader i Newtonsoft.Json.JsonTextReader
. Ta otoka zjednoczyłaby obszar powierzchni publicznej podczas izolowania różnic behawioralnych. Dzięki temu można odizolować zmiany głównie do konstrukcji typu wraz z przekazaniem nowego typu według odwołania. Jest to wzorzec, który jest zgodny z biblioteką Microsoft.Extensions.DependencyModel :
Utf8JsonWriter vs. JsonTextWriter
System.Text.Json.Utf8JsonWriter to wysokowydajny sposób pisania zakodowanego w formacie UTF-8 tekstu JSON z typowych typów platformy .NET, takich jak String
, Int32
i DateTime
. Moduł zapisywania jest typem niskiego poziomu, który może służyć do tworzenia niestandardowych serializatorów.
Zapisywanie wartości pierwotnych
Newtonsoft.Json
ma metodę WriteRawValue
, która zapisuje nieprzetworzone dane JSON, w których oczekiwana jest wartość.
System.Text.Json ma bezpośredni odpowiednik: Utf8JsonWriter.WriteRawValue. Aby uzyskać więcej informacji, zobacz Zapisywanie nieprzetworzonych danych JSON.
Dostosowywanie formatu JSON
JsonTextWriter
zawiera następujące ustawienia, dla których Utf8JsonWriter nie ma odpowiednika:
-
QuoteChar — określa znak, który ma być używany do ujęć wartości ciągów.
Utf8JsonWriter
zawsze używa cudzysłowów podwójnych. -
QuoteName — określa, czy należy otaczać nazwy właściwości cudzysłowami.
Utf8JsonWriter
zawsze otacza je cudzysłowami.
Począwszy od platformy .NET 9, można dostosować znak i rozmiar wcięcia, Utf8JsonWriter aby użyć opcji uwidocznionych przez JsonWriterOptions strukturę:
JsonTextWriter
zawiera następujące ustawienia, dla których Utf8JsonWriter
nie ma odpowiednika:
-
Wcięcie — określa liczbę znaków do wcięcia.
Utf8JsonWriter
zawsze wcięcie o 2 znaki. -
IndentChar — określa znak, który ma być używany do wcięcia.
Utf8JsonWriter
zawsze używa białych znaków. -
QuoteChar — określa znak, który ma być używany do ujęć wartości ciągów.
Utf8JsonWriter
zawsze używa cudzysłowów podwójnych. -
QuoteName — określa, czy należy otaczać nazwy właściwości cudzysłowami.
Utf8JsonWriter
zawsze otacza je cudzysłowami.
Nie ma obejść, które umożliwiają dostosowanie kodu JSON utworzonego w Utf8JsonWriter
ten sposób.
Zapisywanie wartości przedziału czasu, identyfikatora URI lub znaku
JsonTextWriter
Udostępnia WriteValue
metody wartości TimeSpan, Uri i char .
Utf8JsonWriter
nie ma równoważnych metod. Zamiast tego sformatuj te wartości jako ciągi (wywołując ToString()
na przykład , i wywołaj metodę WriteStringValue.
Wiele obiektów docelowych do pisania kodu JSON
Jeśli musisz nadal korzystać Newtonsoft.Json
z niektórych platform docelowych, możesz mieć wiele implementacji i mieć dwie implementacje. Nie jest to jednak proste i wymagałoby duplikowania niektórych #ifdefs
i źródłowych. Jednym ze sposobów udostępniania jak największej ilości kodu jest utworzenie otoki wokół Utf8JsonWriter i Newtonsoft.Json.JsonTextWriter
. Ta otoka zjednoczyłaby obszar powierzchni publicznej podczas izolowania różnic behawioralnych. Dzięki temu można odizolować zmiany głównie do konstrukcji typu.
Biblioteka Microsoft.Extensions.DependencyModel jest następująca:
TypeNameHandling.All nie jest obsługiwany
Decyzja o wykluczeniu TypeNameHandling.All
funkcji równoważnych z System.Text.Json
funkcji była celowa. Zezwalanie ładunkowi JSON na określanie własnych informacji o typie jest typowym źródłem luk w zabezpieczeniach w aplikacjach internetowych. W szczególności skonfigurowanie za pomocą Newtonsoft.Json
TypeNameHandling.All
polecenia umożliwia klientowi zdalnemu osadzanie całej aplikacji wykonywalnego w samym ładunku JSON, dzięki czemu podczas deserializacji aplikacja internetowa wyodrębnia i uruchamia osadzony kod. Aby uzyskać więcej informacji, zobacz piątek 13 ataków JSON w programie PowerPoint i piątek 13. szczegóły ataków JSON.
Zapytania ścieżki JSON nie są obsługiwane
Dom JsonDocument
nie obsługuje wykonywania zapytań przy użyciu ścieżki JSON.
W modelu JsonNode DOM każde JsonNode
wystąpienie ma metodę zwracającą GetPath
ścieżkę do tego węzła. Nie ma jednak wbudowanego interfejsu API do obsługi zapytań opartych na ciągach zapytania ścieżki JSON.
Aby uzyskać więcej informacji, zobacz problem dotnet/runtime #31068 GitHub.
Niektóre limity nie można skonfigurować
System.Text.Json ustawia limity, których nie można zmienić dla niektórych wartości, takich jak maksymalny rozmiar tokenu w znakach (166 MB) i podstawowy 64 (125 MB). Aby uzyskać więcej informacji, zobacz JsonConstants
w kodzie źródłowym i problemie z usługą GitHub dotnet/runtime #39953.
NaN, Infinity, -Infinity
Newtonsoft analizuje NaN
tokeny ciągów , Infinity
i -Infinity
JSON. W programie System.Text.Jsonużyj polecenia JsonNumberHandling.AllowNamedFloatingPointLiterals. Aby uzyskać informacje na temat używania tego ustawienia, zobacz Zezwalanie na liczby w cudzysłowie lub zapisywanie ich.
Migrowanie za pomocą narzędzia GitHub Copilot
Możesz uzyskać pomoc dotyczącą kodowania z witryny GitHub Copilot, aby przekonwertować kod w środowisku IDE.
Jeśli używasz programu Visual Studio 2022 w wersji 17.8 lub nowszej, możesz wypróbować narzędzie GitHub Copilot oparte na sztucznej inteligencji w programie Visual Studio, aby ułatwić migrację Newtonsoft.Json
kodu do użycia .System.Text.Json
Prześlij swoje pytanie i kod, aby przekonwertować jako monit w oknie czatu copilot, jak w poniższym przykładzie.
Uwaga
Narzędzie GitHub Copilot jest obsługiwane przez sztuczną inteligencję, więc możliwe są niespodzianki i błędy. Upewnij się, że zweryfikowano wygenerowany kod lub sugestie. Aby uzyskać więcej informacji na temat ogólnego użycia narzędzia GitHub Copilot, wpływu produktu, nadzoru ludzkiego i prywatności, zobacz GitHub Copilot — często zadawane pytania.
Przykładowy monit o czat copilot
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);
Przykładowa odpowiedź czatu copilot
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.
Zwróć uwagę, że wyniki mogą się różnić od tego, co pokazano w tych przykładowych odpowiedziach. Modele sztucznej inteligencji są niedeterministyczne, co oznacza, że mogą zwracać różne odpowiedzi po zadawaniu tego samego pytania. Może to być spowodowane dodatkowym uczeniem się i adaptacją w czasie, odmianą języka, zmianami w kontekście, takimi jak historia czatów i nie tylko.
Możesz użyć funkcji czatu, takich jak polecenia ukośnika, odwołania i wątki, aby ustawić intencję i uzyskać lepsze odpowiedzi z kontekstem o określonym zakresie.
Jeśli na przykład plik filename
kodu jest otwarty w środowisku IDE, możesz odwołać się do pliku w wierszu polecenia copilot Chat z poleceniem "convert #filename
to use System.Text.Json
". Możesz też odwołać się do rozwiązania za pomocą polecenia "konwertuj @workspace
na użycie System.Text.Json
" w oknie czatu lub w wbudowanym czacie.