Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Den här artikeln visar hur du migrerar från Newtonsoft.Json till System.Text.Json.
Namnområdet System.Text.Json innehåller funktioner för serialisering till och deserialisering från JavaScript Object Notation (JSON). Biblioteket System.Text.Json ingår i körningen för .NET Core 3.1 och senare versioner. För andra målramverk, installera NuGet-paketet System.Text.Json. Paketet stöder:
- .NET Standard 2.0 och senare versioner
- .NET Framework 4.6.2 och senare versioner
- .NET Core 2.0, 2.1 och 2.2
Tips
Du kan använda AI-hjälp för att migrera från Newtonsoft.Json.
              System.Text.Json fokuserar främst på prestanda, säkerhet och standardefterlevnad. Den har några viktiga skillnader i standardbeteende och syftar inte till att ha funktionsparitet med Newtonsoft.Json. För vissa scenarier System.Text.Json har för närvarande inga inbyggda funktioner, men det finns rekommenderade lösningar. I andra scenarier är lösningar opraktiska.
Teamet System.Text.Json investerar i att lägga till de funktioner som oftast efterfrågas. Om ditt program är beroende av en funktion som saknas kan du överväga att lämna in ett problem på GitHub-lagringsplatsen dotnet/runtime för att ta reda på om stöd för ditt scenario kan läggas till.
Det mesta av den här artikeln handlar om hur du använder API:et JsonSerializer , men den innehåller även vägledning om hur du använder JsonDocument (som representerar dokumentobjektmodellen eller DOM) Utf8JsonReaderoch Utf8JsonWriter typerna.
I Visual Basic kan du inte använda Utf8JsonReader, vilket också innebär att du inte kan skriva anpassade konverterare. De flesta av de lösningar som presenteras här kräver att du skriver anpassade konverterare. Du kan skriva en anpassad konverterare i C# och registrera den i ett Visual Basic-projekt. Mer information finns i Visual Basic-stöd.
Tabell med skillnader
I följande tabell visas Newtonsoft.Json funktioner och System.Text.Json motsvarigheter. Motsvarigheterna delas in i följande kategorier:
- ✔️ Stöds av inbyggda funktioner. Att få liknande beteende från System.Text.Jsonkan kräva användning av ett attribut eller globalt alternativ.
- 
              ⚠️ Stöds inte, men det går att lösa problemet. Lösningarna är anpassade konverterare, vilket kanske inte ger fullständig paritet med Newtonsoft.Jsonfunktioner. För vissa av dessa tillhandahålls exempelkod som exempel. Om du förlitar dig på de härNewtonsoft.Jsonfunktionerna kräver migreringen ändringar i .NET-objektmodeller eller andra kodändringar.
- 
              ❌ Stöds inte och lösningen är inte praktisk eller möjlig. Om du förlitar dig på dessa Newtonsoft.Jsonfunktioner är migrering inte möjlig utan betydande ändringar.
| Newtonsoft.Json-funktion | System.Text.Json ekvivalent | 
|---|---|
| Skiftlägesokänslig deserialisering som standard | ✔️ Global inställning för PropertyNameCaseInsensitive | 
| Namn på egenskaper i kamelformat | ✔️ Global inställning för PropertyNamingPolicy | 
| Snake-case-egenskapsnamn | ✔️ Namngivningsprincip för snake_case | 
| Minimal teckenundflytning | ✔️ Strikt tecken som flyr, kan konfigureras | 
| NullValueHandling.Ignoreglobala inställning | ✔️ Global defaultIgnoreCondition-alternativ | 
| Tillåt kommentarer | ✔️ Global ReadCommentHandling-inställning | 
| Tillåt avslutande kommatecken | ✔️ Global allowTrailingCommas-inställning | 
| Registrering av anpassad konverterare | ✔️ Prioritetsordningen skiljer sig åt | 
| Standard maximalt djup 64, konfigurerbart | ✔️ Förinställt maxdjup 64, konfigurerbart | 
| PreserveReferencesHandlingglobala inställning | ✔️ Global inställning för ReferenceHandling | 
| Serialisera eller deserialisera tal inom citattecken | ✔️ Global numberhandling-inställning, [JsonNumberHandling]-attribut | 
| Deserialisera till oföränderliga klasser och strukturer | ✔️ JsonConstructor, C# 9 Poster | 
| Stöd för fält | ✔️ Global inställning för IncludeFields, attributet [JsonInclude] | 
| DefaultValueHandlingglobala inställning | ✔️ Global inställning för DefaultIgnoreCondition | 
| NullValueHandlinginställningen på[JsonProperty] | ✔️ JsonIgnore-attribut | 
| DefaultValueHandlinginställningen på[JsonProperty] | ✔️ JsonIgnore-attribut | 
| Deserialisera Dictionarymed icke-strängnyckel | ✔️ Stödd | 
| Stöd för icke-offentliga egenskapssättare och -hämtare | ✔️ JsonInclude-attribut | 
| [JsonConstructor]-attribut | ✔️ [JsonConstructor]-attribut | 
| ReferenceLoopHandlingglobala inställning | ✔️ Global inställning för ReferenceHandling | 
| Återanrop | ✔️ Återuppringningar | 
| NaN, Infinity, -Infinity | ✔️ Stödd | 
| Requiredinställning för[JsonProperty]attribut | ✔️ [JsonRequired] attribut och C# nödvändig modifikator | 
| DefaultContractResolverför att ignorera egenskaper | ✔️ DefaultJsonTypeInfoResolver-klass | 
| Polymorf serialisering | ✔️ [JsonDerivedType]-attribut | 
| Polymorf deserialisering | ✔️ Ange diskriminator på attributet [JsonDerivedType] | 
| Deserialisera stränguppräkningsvärde | ✔️ Deserialisera enum-strängvärden | 
| MissingMemberHandlingglobala inställning | ✔️ Hantera saknade medlemmar | 
| Fyll i egenskaper utan setters | ✔️ Fyll i egenskaper utan setters | 
| ObjectCreationHandlingglobala inställning | ✔️ Återanvänd i stället för att ersätta egenskaper | 
| Stöd för ett brett spektrum av typer | ⚠️ Vissa typer kräver anpassade konverterare | 
| Deserialisera härledd typ till objectegenskaper | ⚠️ Stöds inte, lösning, exempel | 
| Deserialisera JSON-literal nulltill värdetyper som inte kan nulliseras | ⚠️ Stöds inte, lösning, exempel | 
| DateTimeZoneHandling,DateFormatStringinställningar | ⚠️ Stöds inte, lösning, exempel | 
| JsonConvert.PopulateObjectmetod | ⚠️ Stöds inte, lösning | 
| Stöd för System.Runtime.Serializationattribut | ⚠️ Stöds inte, lösning, exempel | 
| JsonObjectAttribute | ⚠️ Stöds inte, lösning | 
| Tillåt egenskapsnamn utan citattecken | ❌ Stöds inte av design | 
| Tillåt enkla citattecken runt strängvärden | ❌ Stöds inte av design | 
| Tillåt JSON-värden som inte är strängar för strängegenskaper | ❌ Stöds inte av design | 
| TypeNameHandling.Allglobala inställning | ❌ Stöds inte av design | 
| Stöd för JsonPathfrågor | ❌ Stöds ej | 
| Konfigurerbara gränser | ❌ Stöds ej | 
Det här är inte en fullständig lista över Newtonsoft.Json funktioner. Listan innehåller många av de scenarier som har begärts i GitHub-problem eller StackOverflow-inlägg . Om du implementerar en lösning för ett av scenarierna som visas här som för närvarande inte har exempelkod, och om du vill dela din lösning väljer du Den här sidan i avsnittet Feedback längst ned på den här sidan. Det skapar ett problem i den här dokumentationens GitHub-lagringsplats och listar det i avsnittet Feedback på den här sidan också.
Skillnader i standardbeteende
              System.Text.Json är strikt som standard och undviker alla gissningar eller tolkningar för anroparens räkning, med betoning på deterministiskt beteende. Biblioteket är avsiktligt utformat på det här sättet för prestanda och säkerhet. 
              Newtonsoft.Json är flexibel som standard. Den här grundläggande skillnaden i design ligger bakom många av följande specifika skillnader i standardbeteende.
Skiftlägesokänslig deserialisering
Under deserialiseringen, gör Newtonsoft.Json skiftlägesokänslig matchning av egenskapsnamn som standard. Standardvärdet System.Text.Json är skiftlägeskänsligt, vilket ger bättre prestanda eftersom det gör en exakt matchning. För information om hur man gör skiftlägesokänslig matchning, se Skiftlägesokänslig egenskapsmatchning.
Om du använder System.Text.Json indirekt med hjälp av ASP.NET Core behöver du inte göra något för att få beteende som Newtonsoft.Json. ASP.NET Core anger inställningarna för kamel-casing egenskapsnamn och skiftlägesokänslig matchning när den använder System.Text.Json.
ASP.NET Core möjliggör också deserialisering av citerade tal som standard.
Minimal teckenundflytning
Under serialiseringen Newtonsoft.Json är det relativt tillåtande att släppa igenom tecken utan att ta bort dem. Det innebär att den inte ersätter dem med \uxxxx var xxxx är tecknets kodpunkt. När det undflyr dem sker det genom att skicka ut en \ före tecknet, till exempel " blir \". 
              System.Text.Json maskerar som standard fler tecken för att ge skydd på djupet mot XSS-attacker (cross-site scripting) eller informationsexponering och gör det med hjälp av sekvensen med sex tecken. 
              System.Text.Json undflyr alla icke-ASCII-tecken som standard, så du behöver inte göra något om du använder StringEscapeHandling.EscapeNonAscii i Newtonsoft.Json. 
              System.Text.Json undflyr också HTML-känsliga tecken som standard. Information om hur du åsidosätter standardbeteendet System.Text.Json finns i Anpassa teckenkodning.
Kommentarer
Under deserialiseringen Newtonsoft.Json ignorerar kommentarer i JSON som standard. Standardvärdet System.Text.Json är att utlösa undantag för kommentarer eftersom RFC 8259-specifikationeninte innehåller dem. Information om hur du tillåter kommentarer finns i Tillåt kommentarer och avslutande kommatecken.
Avslutande kommatecken
Under deserialiseringen Newtonsoft.Json ignorerar efterföljande kommatecken som standard. Den ignorerar också flera avslutande kommatecken (till exempel [{"Color":"Red"},{"Color":"Green"},,]). Standardvärdet System.Text.Json är att utlösa undantag för avslutande kommatecken eftersom RFC 8259-specifikationen  inte tillåter dem. För information om hur du får System.Text.Json att acceptera dem, se Tillåt kommentarer och avslutande kommatecken. Det finns inget sätt att tillåta flera avslutande kommatecken.
Prioritet för registrering av konverterare
Registreringspriorensen Newtonsoft.Json för anpassade konverterare är följande:
- Attribut för egenskapen
- Attribut på typ
- Samling av konverterare
Den här ordningen innebär att en anpassad konverterare i Converters samlingen åsidosätts av en konverterare som registreras genom att ett attribut tillämpas på typnivå. Båda registreringarna åsidosätts av ett attribut på egenskapsnivå.
Registreringspriorensen System.Text.Json för anpassade konverterare skiljer sig:
- Attribut för egenskapen
- Converters samling
- Attribut på typ
Skillnaden här är att en anpassad konverterare i Converters samlingen åsidosätter ett attribut på typnivå. Avsikten med den här prioritetsordningen är att göra ändringar vid körning åsidosätta val som görs vid designtid. Det finns inget sätt att ändra prioriteten.
Mer information om registrering av anpassade konverterare finns i Registrera en anpassad konverterare.
Maximalt djup
Den senaste versionen av Newtonsoft.Json har en maximal djupgräns på 64 som standard. 
              System.Text.Json har också en standardgräns på 64 och kan konfigureras genom att ange JsonSerializerOptions.MaxDepth.
Om du använder System.Text.Json indirekt med hjälp av ASP.NET Core är standardgränsen för maximalt djup 32. Standardvärdet är samma som för modellbindning och anges i klassen JsonOptions.
JSON-strängar (egenskapsnamn och strängvärden)
Under deserialiseringen kan Newtonsoft.Json acceptera egenskapsnamn som kan vara omgivna av dubbla citattecken, enkla citattecken eller utan citattecken. Det accepterar strängvärden som omges av dubbelcitat eller enkelcitat. Accepterar till exempel Newtonsoft.Json följande JSON:
{
  "name1": "value",
  'name2': "value",
  name3: 'value'
}
              System.Text.Jsonaccepterar endast egenskapsnamn och strängvärden inom dubbla citattecken eftersom formatet krävs av RFC 8259-specifikationen  och är det enda format som anses vara giltigt JSON.
Ett värde som omges av enkla citattecken resulterar i en JsonException med följande meddelande:
''' is an invalid start of a value.
Värden som inte är strängvärden för strängegenskaper
              Newtonsoft.Json accepterar icke-strängvärden, till exempel ett tal eller literaler true och false, för deserialisering till egenskaper av typen sträng. Här är ett exempel på JSON som Newtonsoft.Json deserialiserar till följande klass:
{
  "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 deserialiserar inte icke-strängvärden till strängegenskaper. Ett icke-strängvärde som tas emot för ett strängfält resulterar i en JsonException med följande meddelande:
The JSON value could not be converted to System.String.
Scenarier med JsonSerializer
Några av följande scenarier stöds inte av inbyggda funktioner, men det är möjligt med lösningar. Lösningarna är anpassade konverterare, vilket kanske inte ger fullständig paritet med Newtonsoft.Json funktioner. För vissa av dessa tillhandahålls exempelkod som exempel. Om du förlitar dig på de här Newtonsoft.Json funktionerna kräver migreringen ändringar i .NET-objektmodeller eller andra kodändringar.
För några av följande scenarier är lösningar inte praktiska eller möjliga. Om du förlitar dig på dessa Newtonsoft.Json funktioner är migrering inte möjlig utan betydande ändringar.
Tillåt eller skriv tal inom citattecken
              Newtonsoft.Json kan serialisera eller deserialisera tal som representeras av JSON-strängar (omgivna av citattecken). Den kan till exempel acceptera: {"DegreesCelsius":"23"} i stället {"DegreesCelsius":23}för . Om du vill aktivera det beteendet i System.Text.Jsonanger du JsonSerializerOptions.NumberHandling till WriteAsString eller AllowReadingFromStringeller använder attributet [JsonNumberHandling].
Om du använder System.Text.Json indirekt med hjälp av ASP.NET Core behöver du inte göra något för att få beteende som Newtonsoft.Json. ASP.NET Core anger webbstandarder när den använder System.Text.Json, och webbstandarder tillåter citerade tal.
Mer information finns i Tillåt eller skriva tal inom citattecken.
Ange konstruktor som ska användas vid deserialisering
Med Newtonsoft.Json[JsonConstructor] attributet kan du ange vilken konstruktor som ska anropas vid deserialisering till en POCO.
              System.Text.Json har också ett [JsonConstructor]- attribut. Mer information finns i Oföränderliga typer och records.
Ignorera en egenskap villkorligt
              Newtonsoft.Json har flera sätt att villkorligt ignorera en egenskap för serialisering eller deserialisering:
- 
              DefaultContractResolverlåter dig välja egenskaper som ska inkluderas eller ignoreras baserat på godtyckliga kriterier.
- Med NullValueHandlinginställningarna ochDefaultValueHandlingpåJsonSerializerSettingskan du ange att alla null-värde- eller standardvärdeegenskaper ska ignoreras.
- Med NullValueHandlinginställningarna ochDefaultValueHandlingför[JsonProperty]attributet kan du ange enskilda egenskaper som ska ignoreras när värdet är null eller standardvärdet.
System.Text.Json tillhandahåller följande sätt att ignorera egenskaper eller fält vid serialisering:
- Attributet [JsonIgnore] på en egenskap gör att egenskapen utelämnas från JSON under serialiseringen.
- Det globala alternativet IgnoreReadOnlyProperties låter dig ignorera alla skrivskyddade egenskaper.
- Om du inkluderar fält kan du med det JsonSerializerOptions.IgnoreReadOnlyFields globala alternativet ignorera alla skrivskyddade fält.
- Med DefaultIgnoreConditiondet globala alternativet kan du ignorera alla värdetypsegenskaper som har standardvärden eller ignorera alla referenstypsegenskaper som har null-värden.
I .NET 7 och senare versioner kan du dessutom anpassa JSON-kontraktet för att ignorera egenskaper baserat på godtyckliga kriterier. Mer information finns i Anpassade kontrakt.
Offentliga och icke-offentliga fält
              Newtonsoft.Json kan serialisera och deserialisera fält samt egenskaper.
I System.Text.Jsonanvänder du den JsonSerializerOptions.IncludeFields globala inställningen eller attributet [JsonInclude] för att inkludera offentliga fält vid serialisering eller deserialisering. Ett exempel finns i Inkludera fält.
Bevara objektreferenser och hantera loopar
Som standard Newtonsoft.Json serialiserar efter värde. Om ett objekt till exempel innehåller två egenskaper som innehåller en referens till samma Person objekt dupliceras värdena Person för objektets egenskaper i JSON.
              Newtonsoft.Json har en PreserveReferencesHandling inställning på JsonSerializerSettings som gör att du kan serialisera med referens:
- En identifierarmetadata läggs till i den JSON som skapades för det första Personobjektet.
- JSON som skapas för det andra Personobjektet innehåller en referens till identifieraren i stället för egenskapsvärden.
              Newtonsoft.Json har också en ReferenceLoopHandling inställning som gör att du kan ignorera cirkelreferenser i stället för att utlösa ett undantag.
Om du vill bevara referenser och hantera cirkelreferenser i System.Text.Jsonanger du JsonSerializerOptions.ReferenceHandler till Preserve. Inställningen ReferenceHandler.Preserve motsvarar PreserveReferencesHandling = PreserveReferencesHandling.All i Newtonsoft.Json.
Alternativet ReferenceHandler.IgnoreCycles har ett beteende som liknar Newtonsoft.JsonReferenceLoopHandling.Ignore. En skillnad är att implementeringen System.Text.Json ersätter referensslingor med null JSON-token i stället för att ignorera objektreferensen. Mer information finns i Ignorera cirkelreferenser.
Newtonsoft.Json Precis som ReferenceResolverSystem.Text.Json.Serialization.ReferenceResolver definierar klassen beteendet att bevara referenser för serialisering och deserialisering. Skapa en härledd klass för att ange anpassat beteende. Ett exempel finns i GuidReferenceResolver.
Vissa relaterade Newtonsoft.Json funktioner stöds inte:
Mer information finns i Bevara referenser och hantera cirkelreferenser.
Ordlista med annan typ av nyckel än sträng
Både Newtonsoft.Json och System.Text.Json stöder samlingar av typen Dictionary<TKey, TValue>. För information om vilka nyckeltyper som stöds, se nyckeltyper som stöds.
Varning
Deserialisera till en Dictionary<TKey, TValue> plats där TKey skrivs som något annat än string kan medföra en säkerhetsrisk i det förbrukande programmet. Mer information finns i dotnet/runtime#4761.
Typer utan inbyggt stöd
System.Text.Json ger inte inbyggt stöd för följande typer:
- DataTable och relaterade typer (mer information finns i typer som stöds)
- ExpandoObject
- TimeZoneInfo
- BigInteger
- DBNull
- Type
- ValueTuple och dess associerade generiska typer
Anpassade konverterare kan implementeras för typer som inte har inbyggt stöd.
Polymorf serialisering
              Newtonsoft.Json utför automatiskt polymorf serialisering. Från och med .NET 7 System.Text.Json stöder polymorf serialisering via attributet JsonDerivedTypeAttribute . Mer information finns i Serialisera egenskaper för härledda klasser.
Polymorf deserialisering
              Newtonsoft.Json har en TypeNameHandling inställning som lägger till typnamnsmetadata till JSON vid serialisering. Det använder metadata vid deserialisering för att utföra polymorf deserialisering. Från och med .NET 7 System.Text.Json förlitar sig på typdiskriminerande information för att utföra polymorf deserialisering. Dessa metadata genereras i JSON och används sedan under deserialiseringen för att avgöra om deserialisera till bastypen eller en härledd typ. Mer information finns i Serialisera egenskaper för härledda klasser.
Om du vill stödja polymorf deserialisering i äldre .NET-versioner skapar du en konverterare som exemplet i Så här skriver du anpassade konverterare.
Deserialisera stränguppräkningsvärden
Som standard, System.Text.Json stöder inte deserialisering av stränguppräkningsvärden, medan Newtonsoft.Json däremot gör det. Följande kod genererar till exempel en 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
}
Du kan dock aktivera deserialisering av stränguppräkningsvärden med hjälp av JsonStringEnumConverter-konverteraren. Mer information finns i Enumereringar som strängar.
Deserialisering av objektegenskaper
När Newtonsoft.Json deserialiserar till Object, det:
- Härleder typen av primitiva värden i JSON-nyttolasten (förutom null) och returnerar lagradestring,long,double,booleanellerDateTimesom ett rutat objekt. Primitiva värden är enkla JSON-värden, till exempel ett JSON-tal, en sträng,true,falseellernull.
- Returnerar ett JObjectellerJArrayför komplexa värden i JSON-nyttolasten. Komplexa värden är samlingar av JSON-nyckel/värde-par inom klammerparenteser ({}) eller listor med värden inom hakparenteser ([]). Egenskaper och värden inom klammerparenteser eller hakparenteser kan ha ytterligare egenskaper eller värden.
- Returnerar en null-referens när nyttolasten har JSON-literalen null.
              System.Text.Json lagrar en låda JsonElement för både primitiva och komplexa värden när den deserialiseras till Object, till exempel:
- En objectegenskap.
- Ett objectordlistevärde.
- Ett objectmatrisvärde.
- En rot object.
Dock behandlar System.Text.Jsonnull på samma sätt som Newtonsoft.Json och returnerar en null-referens när nyttolasten har "JSON-literalen" null i sig.
Om du vill implementera typinferens för object egenskaper skapar du en konverterare som exemplet i Så här skriver du anpassade konverterare.
Deserialisera null till icke-nullbar typ
              Newtonsoft.Json utlöser inget undantag i följande scenario:
- 
              NullValueHandlingär inställt påIgnore, och
- Under deserialiseringen innehåller JSON ett null-värde för en värdetyp som inte kan nulliseras.
I samma scenario utlöser System.Text.Json ett undantag. (Motsvarande null-hanteringsinställning i System.Text.Json är JsonSerializerOptions.IgnoreNullValues = true.)
Om du äger måltypen är den bästa lösningen att göra egenskapen i fråga nullbar (till exempel ändra int till int?).
En annan lösning är att skapa en konverterare för typen, till exempel följande exempel som hanterar null-värden för DateTimeOffset typer:
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);
    }
}
Registrera den här anpassade konverteraren med hjälp av ett attribut på egenskapen eller genom att lägga till konverteraren i Converters samlingen.
              
               Obs! Den föregående konverteraren hanterar null-värden på ett annat sätt än Newtonsoft.Json för POCO:er som anger standardvärden. Anta till exempel att följande kod representerar målobjektet:
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; }
}
Och anta att följande JSON deserialiseras med hjälp av föregående konverterare:
{
  "Date": null,
  "TemperatureCelsius": 25,
  "Summary": null
}
Efter deserialiseringen Date har egenskapen 1/1/0001 (default(DateTimeOffset)), dvs. värdet som anges i konstruktorn skrivs över. Med samma POCO och JSON skulle Newtonsoft.Json-deserialisering lämna kvar 1/1/2001 i Date-egenskapen.
Deserialisera till oföränderliga klasser och strukturer
              Newtonsoft.Json kan deserialisera till oföränderliga klasser och structs eftersom den kan använda konstruktorer som har parametrar.
I System.Text.Jsonanvänder du attributet [JsonConstructor] för att ange användning av en parameteriserad konstruktor. Poster i C# 9 är också oföränderliga och stöds som deserialiseringsmål. Mer information finns i Oföränderliga typer och records.
Nödvändiga egenskaper
I Newtonsoft.Json anger du att en egenskap är obligatorisk genom att sätta Required på attributet [JsonProperty]. 
              Newtonsoft.Json genererar ett undantag om inget värde tas emot i JSON för en egenskap som har markerats som obligatorisk.
Från och med .NET 7 kan du använda C# required -modifieraren eller JsonRequiredAttribute attributet på en obligatorisk egenskap. 
              System.Text.Json genererar ett undantag om JSON-nyttolasten inte innehåller något värde för den markerade egenskapen. Mer information finns i Obligatoriska egenskaper.
Ange datumformat
              Newtonsoft.Json innehåller flera sätt att styra hur egenskaper hos DateTime- och DateTimeOffset-typer serialiseras och deserialiseras.
- Inställningen DateTimeZoneHandlingkan användas för att serialisera allaDateTimevärden som UTC-datum.
- Inställningen DateFormatStringochDateTimekonverterarna kan användas för att anpassa formatet för datumsträngar.
              System.Text.Json stöder ISO 8601-1:2019, inklusive RFC 3339-profilen. Det här formatet är allmänt antaget, entydigt och möjliggör exakta rundresor. Om du vill använda andra format skapar du en anpassad konverterare. Till exempel serialiserar och deserialiserar följande konverterare JSON som använder Unix-epokformat med eller utan en tidszonsförskjutning (värden som /Date(1590863400000-0700)/ eller /Date(1590863400000)/):
sealed class UnixEpochDateTimeOffsetConverter : System.Text.Json.Serialization.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, NumberStyles.Integer, CultureInfo.InvariantCulture, out long unixTime)
                || !int.TryParse(match.Groups[3].Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out int hours)
                || !int.TryParse(match.Groups[4].Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out int minutes))
        {
            throw new System.Text.Json.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 = value.ToUnixTimeMilliseconds();
        TimeSpan utcOffset = value.Offset;
        string formatted = string.Create(
            CultureInfo.InvariantCulture,
            $"/Date({unixTime}{(utcOffset >= TimeSpan.Zero ? "+" : "-")}{utcOffset:hhmm})/");
        writer.WriteStringValue(formatted);
    }
}
sealed class UnixEpochDateTimeConverter : System.Text.Json.Serialization.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, NumberStyles.Integer, CultureInfo.InvariantCulture, out long unixTime))
        {
            throw new System.Text.Json.JsonException();
        }
        return s_epoch.AddMilliseconds(unixTime);
    }
    public override void Write(
        Utf8JsonWriter writer,
        DateTime value,
        JsonSerializerOptions options)
    {
        long unixTime = (value - s_epoch).Ticks / TimeSpan.TicksPerMillisecond;
        string formatted = string.Create(CultureInfo.InvariantCulture, $"/Date({unixTime})/");
        writer.WriteStringValue(formatted);
    }
}
Mer information finns i Stöd för DateTime och DateTimeOffset i System.Text.Json.
Återanrop
              Newtonsoft.Json låter dig köra anpassad kod på flera punkter i serialiserings- eller deserialiseringsprocessen:
- OnDeserializing (när du börjar deserialisera ett objekt)
- OnDeserialized (när det är klart att deserialisera ett objekt)
- OnSerializing (när du börjar serialisera ett objekt)
- OnSerialized (när du är klar med serialiseringen av ett objekt)
System.Text.Json exponerar samma meddelanden under serialisering och deserialisering. Om du vill använda dem implementerar du ett eller flera av följande gränssnitt från System.Text.Json.Serialization namnområdet:
Här är ett exempel som söker efter en null-egenskap och skriver meddelanden i början och slutet av serialisering och deserialisering:
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=
Koden OnDeserializing har inte åtkomst till den nya POCO-instansen. Om du vill ändra den nya POCO-instansen i början av deserialiseringen placerar du koden i POCO-konstruktorn.
Icke-offentliga egenskapssättare och hämtare
              Newtonsoft.Json kan använda privata och interna setters och getters för egenskaper via attributet JsonProperty.
System.Text.Json stöder privata och interna setters och getters via attributet [JsonInclude]. Exempelkod finns i Icke-offentliga egenskapsåtkomster.
Fylla i befintliga objekt
Metoden JsonConvert.PopulateObject i Newtonsoft.Json deserialiserar ett JSON-dokument till en befintlig instans av en klass, i stället för att skapa en ny instans. 
              System.Text.Json skapar alltid en ny instans av måltypen med hjälp av standardkonstruktorn utan offentliga parametrar. Anpassade konverterare kan deserialisera till en befintlig instans.
Återanvänd i stället för att ersätta egenskaper
Från och med .NET 8 System.Text.Json har stöd för återanvändning av initierade egenskaper i stället för att ersätta dem. Det finns vissa skillnader i beteende som du kan läsa om i API-förslaget.
Mer information finns i Fyll i initierade egenskaper.
Fyll i egenskaper utan setters
Från och med .NET 8 System.Text.Json har stöd för att fylla i egenskaper, inklusive de som inte har en setter. Mer information finns i Fyll i initierade egenskaper.
Namngivningsprincip för ormfall
              System.Text.Json innehåller en inbyggd namngivningsprincip för snake case. Det finns dock vissa beteendeskillnader med Newtonsoft.Json för vissa indata. I följande tabell visas några av dessa skillnader när du konverterar indata med hjälp av JsonNamingPolicy.SnakeCaseLower principen.
| Indata | Newtonsoft.Json resultat | System.Text.Json resultat | 
|---|---|---|
| AB1 | "a_b1" | "ab1" | 
| SHA512Managed | "sh_a512_managed" | "sha512_managed" | 
| "abc123DEF456" | "abc123_de_f456" | "abc123_def456" | 
| KEBAB-CASE | keba_b-_case | "kebab-case" | 
System.Runtime.Serialization-attributer
System.Runtime.Serialization attribut som DataContractAttribute, DataMemberAttributeoch IgnoreDataMemberAttribute låter dig definiera ett datakontrakt. Ett datakontrakt är ett formellt avtal mellan en tjänst och en klient som abstrakt beskriver de data som ska utbytas. Datakontraktet definierar exakt vilka egenskaper som serialiseras för utbyte.
System.Text.Json har inte inbyggt stöd för dessa attribut. Från och med .NET 7 kan du dock använda en anpassad typlösare för att lägga till stöd. Ett exempel finns i ZCS. DataContractResolver.
Oktalnummer
              Newtonsoft.Json behandlar tal med inledande nolla som oktala tal. 
              System.Text.Jsontillåter inte inledande nolla eftersom RFC 8259-specifikationen  inte tillåter dem.
Hantera saknade medlemmar
Om den JSON som deserialiseras innehåller egenskaper som saknas i måltypen kan Newtonsoft.Json konfigureras för att utlösa undantag. Som standard System.Text.Json ignorerar extra egenskaper i JSON, förutom när du använder attributet [JsonExtensionData].
I .NET 8 och senare versioner kan du ange om du vill hoppa över eller inte tillåta ommappade JSON-egenskaper med något av följande sätt:
- Använd JsonUnmappedMemberHandlingAttribute-attributet till den typ som du deserialiserar.
- För att ställa in din inställning globalt, ange egenskapen JsonSerializerOptions.UnmappedMemberHandling. Eller för källgenerering, ange du JsonSourceGenerationOptionsAttribute.UnmappedMemberHandling egenskapen och tillämpa attributet på din JsonSerializerContext klass.
- Anpassa egenskapen JsonTypeInfo.UnmappedMemberHandling .
JsonObjectAttribute
              Newtonsoft.Json har ett attribut, JsonObjectAttribute, som kan tillämpas på typnivå för att styra vilka medlemmar som serialiseras, hur null värden hanteras och om alla medlemmar krävs. 
              System.Text.Json har inget motsvarande attribut som kan tillämpas på en typ. För vissa beteenden, till exempel null värdehantering, kan du konfigurera samma beteende antingen globalt JsonSerializerOptions eller individuellt på varje egenskap med hjälp av JsonIgnoreAttribute.
Tänk på följande exempel som används Newtonsoft.Json.JsonObjectAttribute för att ange att alla null egenskaper ska ignoreras:
[JsonObject(ItemNullValueHandling = NullValueHandling.Ignore)]
public class Person { ... }
I System.Text.Jsonkan du ange beteendet för alla typer och egenskaper:
JsonSerializerOptions options = new()
{
    DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
};
string json = JsonSerializer.Serialize<Person>(person, options);
Eller så kan du ange beteendet för varje egenskap separat:
public class Person
{
    [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
    public string? Name { get; set; }
    [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
    public int? Age { get; set; }
}
Tänk sedan på följande exempel som används Newtonsoft.Json.JsonObjectAttribute för att ange att alla medlemsegenskaper måste finnas i JSON:
[JsonObject(ItemRequired = Required.Always)]
public class Person { ... }
Du kan uppnå samma beteende i System.Text.Json genom att lägga till C#- required modifieraren eller JsonRequiredAttributetill varje egenskap. Mer information finns i Obligatoriska egenskaper.
public class Person
{
    [JsonRequired]
    public string? Name { get; set; }
    public required int? Age { get; set; }
}
Tänk slutligen på följande exempel som används Newtonsoft.Json.JsonObjectAttribute för att ange en rubrik för JSON-schemagenerering:
[JsonObject(Title = "PersonTitle")]
public class Person { ... }
Egenskapen Title används för JSON-schemametadata och har ingen direkt motsvarighet i System.Text.Json. Från och med .NET 9 kan du använda JsonSchemaExporter för att generera JSON-scheman och anpassa schemarubriken med hjälp av ombudet TransformSchemaNode . Ett exempel finns i Transformera det genererade schemat.
TraceWriter
              Newtonsoft.Json låter dig felsöka med hjälp av en TraceWriter för att visa loggar som genereras av serialisering eller deserialisering. 
              System.Text.Json utför inte loggning.
JsonDocument och JsonElement jämfört med JToken (som JObject, JArray)
              System.Text.Json.JsonDocument ger möjlighet att parsa och skapa en skrivskyddad dokumentobjektmodell (DOM) från befintliga JSON-nyttolaster. DOM ger slumpmässig åtkomst till data i en JSON-nyttolast. JSON-elementen som utgör nyttolasten kan nås via JsonElement typen . Typen JsonElement innehåller API:er för att konvertera JSON-text till vanliga .NET-typer. 
              JsonDocument exponerar en RootElement egenskap.
Från och med .NET 6 kan du parsa och skapa en föränderlig DOM från befintliga JSON-nyttolaster med hjälp JsonNode av typen och andra typer i System.Text.Json.Nodes namnområdet. Mer information finns i Använda JsonNode.
JsonDocument är IDisposable
              JsonDocument skapar en minnesintern vy över data till en poolbuffert. Därför, till skillnad från JObject eller JArray från Newtonsoft.Json, implementerar JsonDocument-typen IDisposable och måste användas i ett using-block. Mer information finns i JsonDocument är IDisposable.
JsonDocument är skrivskyddat
DOM System.Text.Json kan inte lägga till, ta bort eller ändra JSON-element. Det är utformat på det här sättet för prestanda och för att minska allokering för parsning av vanliga JSON-nyttolaststorlekar (det vill: < 1 MB).
JsonElement är en unionstruktur
              JsonDocument exponerar RootElement som en egenskap av typen JsonElement, som är en union struct-typ som omfattar alla JSON-element. 
              Newtonsoft.Json använder dedikerade hierarkiska typer som JObject, JArray, JTokenoch så vidare. 
              JsonElement är det du kan söka efter och räkna upp och du kan använda JsonElement för att materialisera JSON-element till .NET-typer.
Från och med .NET 6 kan du använda JsonNode typ och typer i namnområdet System.Text.Json.Nodes som motsvarar JObject, JArrayoch JToken. Mer information finns i Använda JsonNode.
Så här söker du efter underelement i JsonDocument och JsonElement
Sökningar efter JSON-token som använder JObject eller JArray från Newtonsoft.Json tenderar att vara relativt snabba eftersom de är sökningar i någon ordlista. Som jämförelse kräver sökningar på JsonElement en sekventiell sökning av egenskaperna och är därför relativt långsamma (till exempel när du använder TryGetProperty). 
              System.Text.Json är utformad för att minimera den inledande parsningstiden i stället för uppslagstiden. Mer information finns i Så här söker du efter underelement i JsonDocument och JsonElement.
Utf8JsonReader jämfört med JsonTextReader
              System.Text.Json.Utf8JsonReader är en högpresterande, låg allokering, framåtläsande läsare för UTF-8-kodad JSON-text, som läser från antingen en ReadOnlySpan<byte> eller en ReadOnlySequence<byte>. 
              Utf8JsonReader är en lågnivåtyp som kan användas för att skapa anpassade parsers och deserializers.
Utf8JsonReader är en ref-struktur
Det JsonTextReader i Newtonsoft.Json är en klass. Typen Utf8JsonReader skiljer sig åt eftersom det är en referens-struct. Mer information finns i referensstruktureringsbegränsningar för Utf8JsonReader.
Läsa null-värden i null-värdetyper
              Newtonsoft.Json tillhandahåller API:er som returnerar Nullable<T>, till exempel ReadAsBoolean, som hanterar en NullTokenType åt dig genom att returnera en bool?. De inbyggda System.Text.Json API:erna returnerar endast icke-nullbara värdetyper. För mer information, se Läs nullvärden i nullvärdetyper.
Flera syften för att läsa JSON
Om du behöver fortsätta att använda Newtonsoft.Json för vissa målramverk kan du använda flera mål och ha två implementeringar. Detta är dock inte trivialt och skulle kräva viss #ifdefs och källduplicering. Ett sätt att dela så mycket kod som möjligt är att skapa en ref struct omslutning runt Utf8JsonReader och Newtonsoft.Json.JsonTextReader. Den här omslutningen skulle förena den offentliga ytan samtidigt som beteendeskillnaderna isoleras. På så sätt kan du isolera ändringarna främst i konstruktionen av typen, tillsammans med att skicka den nya typen runt som referens. Det här är det mönster som biblioteket Microsoft.Extensions.DependencyModel följer:
Utf8JsonWriter jämfört med JsonTextWriter
              System.Text.Json.Utf8JsonWriter är ett högpresterande sätt att skriva UTF-8-kodad JSON-text från vanliga .NET-typer som String, Int32och DateTime. Skrivaren är en lågnivåtyp som kan användas för att skapa anpassade serialiserare.
Skriv råvärden
              Newtonsoft.Json har en WriteRawValue metod som skriver rå JSON där ett värde förväntas. 
              System.Text.Json har en direkt motsvarighet: Utf8JsonWriter.WriteRawValue. Mer information finns i Skriva rå JSON.
Anpassa JSON-format
              JsonTextWriter innehåller följande inställningar som Utf8JsonWriter inte har någon motsvarighet:
- 
              QuoteChar – Anger det tecken som ska användas för att omge strängvärden. 
              Utf8JsonWriteranvänder alltid dubbla citattecken.
- 
              QuoteName – Anger om egenskapsnamn ska omges av citattecken eller inte. 
              Utf8JsonWriteromger dem alltid med citattecken.
Från och med .NET 9 kan du anpassa indragstecken och storleken för Utf8JsonWriter genom att använda alternativ som exponeras av strukturen: JsonWriterOptions
              JsonTextWriter innehåller följande inställningar som Utf8JsonWriter inte har någon motsvarighet:
- 
              Indrag – Specificerar hur många tecken som ska dras in. 
              Utf8JsonWriterindrag med 2 tecken.
- 
              IndentChar – Anger det tecken som ska användas för indrag. 
              Utf8JsonWriteranvänder alltid blanksteg.
- 
              QuoteChar – Anger det tecken som ska användas för att omge strängvärden. 
              Utf8JsonWriteranvänder alltid dubbla citattecken.
- 
              QuoteName – Anger om egenskapsnamn ska omges av citattecken eller inte. 
              Utf8JsonWriteromger dem alltid med citattecken.
Det finns inga lösningar som gör att du kan anpassa JSON som skapats av Utf8JsonWriter på dessa sätt.
Skriv tidsintervall, Uri eller teckenvärden
              JsonTextWriter innehåller WriteValue metoder för TimeSpan-, Uri- och char-värden . 
              Utf8JsonWriter har inte motsvarande metoder. Formatera i stället dessa värden som strängar (genom att anropa ToString(), till exempel) och anropa WriteStringValue.
Flera destinationer för att skriva JSON
Om du behöver fortsätta att använda Newtonsoft.Json för vissa målramverk kan du använda flera mål och ha två implementeringar. Detta är dock inte trivialt och skulle kräva viss #ifdefs och källduplicering. Ett sätt att dela så mycket kod som möjligt är att skapa en omslutning runt Utf8JsonWriter och Newtonsoft.Json.JsonTextWriter. Den här omslutningen skulle förena den offentliga ytan samtidigt som beteendeskillnaderna isoleras. På så sätt kan du främst isolera ändringarna i typens konstruktion. 
              Microsoft.Extensions.DependencyModel-biblioteket följer:
TypeNameHandling.All stöds inte
Beslutet att undanta TypeNameHandling.All-motsvarande funktioner från System.Text.Json var avsiktligt. Att tillåta en JSON-nyttolast att ange sin egen typinformation är en vanlig källa till sårbarheter i webbprogram. I synnerhet gör konfigurationen Newtonsoft.Json med TypeNameHandling.All att fjärrklienten kan bädda in ett helt körbart program i själva JSON-nyttolasten, så att webbprogrammet extraherar och kör den inbäddade koden under deserialiseringen. Mer information finns i Fredagen den 13:e JSON-attacker presentation och Fredagen den 13:e JSON-attacker detaljer.
JSON-sökvägsfrågor stöds inte
              JsonDocument DOM stöder inte frågor med hjälp av JSON-sökväg.
I en JsonNode DOM har varje JsonNode instans en GetPath metod som returnerar en sökväg till noden. Men det finns inget inbyggt API för att hantera frågor baserat på frågesträngar för JSON-sökväg.
Mer information finns i GitHub-problemet dotnet/runtime #31068.
Vissa gränser kan inte konfigureras
              System.Text.Json anger gränser som inte kan ändras för vissa värden, till exempel den maximala tokenstorleken i tecken (166 MB) och i bas 64 (125 MB). Mer information JsonConstants finns i källkoden och GitHub-problemet dotnet/runtime #39953.
NaN, Infinity, -Infinity
Newtonsoft parsar NaN, Infinityoch -Infinity JSON-strängtoken. Med System.Text.Jsonanvänder du JsonNumberHandling.AllowNamedFloatingPointLiterals. Information om hur du använder den här inställningen finns i Tillåt eller skriva tal inom citattecken.
Använda AI för lösningsomfattande migrering
Du kan använda AI-verktyg, till exempel GitHub Copilot, för att migrera din lösningskod från Newtonsoft.Json till System.Text.Json.
Här är en exempelfråga som du kan använda i Visual Studio Copilot Chat för att migrera en lösning.
Convert all serialization code in this #solution from Newtonsoft.Json to System.Text.Json, using the recommended approach for my current .NET version.
- Update attributes and properties, including rules for skipping or renaming during serialization
- Ensure polymorphic serialization continues to work correctly
- Respect existing custom converters and project-level settings (for example, from the Utilities folder or appsettings.json)
- Update related unit tests and highlight any potential breaking changes
- Generate a migration summary
Granska Copilots förslag innan du tillämpar dem.
Mer information om GitHub Copilot finns i Vanliga frågor och svar om GitHub.