JsonSerializerOptions-példányok példányosítása System.Text.Json
Ez a cikk bemutatja, hogyan kerülheti el a teljesítményproblémák használatát JsonSerializerOptions. Azt is bemutatja, hogyan használhatja az elérhető paraméteres konstruktorokat.
JsonSerializerOptions-példányok újrafelhasználása
Ha ugyanazokat a beállításokat használja JsonSerializerOptions
többször is, ne hozzon létre új JsonSerializerOptions
példányt minden alkalommal, amikor használja. Használja újra ugyanazt a példányt minden híváshoz. Ez az útmutató az egyéni konverterekhez írt kódra, valamint az egyéni konverterek hívására JsonSerializer.Serialize vagy JsonSerializer.Deserializehívására vonatkozik. Több szálon is biztonságosan használhatja ugyanazt a példányt. A beállításpéldány metaadat-gyorsítótárai szálbiztosak, és a példány az első szerializálás vagy deszerializálás után nem módosítható.
Az alábbi kód bemutatja az új beállításpéldányok használatára vonatkozó teljesítménybírságot.
using System.Diagnostics;
using System.Text.Json;
namespace OptionsPerfDemo
{
public record Forecast(DateTime Date, int TemperatureC, string Summary);
public class Program
{
public static void Main()
{
Forecast forecast = new(DateTime.Now, 40, "Hot");
JsonSerializerOptions options = new() { WriteIndented = true };
int iterations = 100000;
var watch = Stopwatch.StartNew();
for (int i = 0; i < iterations; i++)
{
Serialize(forecast, options);
}
watch.Stop();
Console.WriteLine($"Elapsed time using one options instance: {watch.ElapsedMilliseconds}");
watch = Stopwatch.StartNew();
for (int i = 0; i < iterations; i++)
{
Serialize(forecast);
}
watch.Stop();
Console.WriteLine($"Elapsed time creating new options instances: {watch.ElapsedMilliseconds}");
}
private static void Serialize(Forecast forecast, JsonSerializerOptions? options = null)
{
_ = JsonSerializer.Serialize<Forecast>(
forecast,
options ?? new JsonSerializerOptions() { WriteIndented = true });
}
}
}
// Produces output like the following example:
//
//Elapsed time using one options instance: 190
//Elapsed time creating new options instances: 40140
Az előző kód 100 000 alkalommal szerializál egy kis objektumot ugyanazzal a beállításpéldánysal. Ezután szerializálja ugyanazt az objektumot ugyanannyi alkalommal, és minden alkalommal létrehoz egy új beállításpéldányt. A futási idő általában 190 és 40 140 ezredmásodperc között van. A különbség még nagyobb, ha növeli az iterációk számát.
A szerializáló bemelegítési fázison megy keresztül az objektumgráf egyes típusainak első szerializálása során, amikor egy új beállításpéldányt ad át neki. Ez a bemelegítés magában foglalja a metaadatok gyorsítótárának létrehozását, amely a szerializáláshoz szükséges. A metaadatok közé tartoznak a tulajdonságbeolvasók, a setterek, a konstruktorargumentumok, a megadott attribútumok stb. delegáltjai. Ezt a metaadat-gyorsítótárat a beállításpéldány tárolja. Ugyanez a bemelegítési folyamat és gyorsítótár a deszerializálásra vonatkozik.
A példány metaadat-gyorsítótárának JsonSerializerOptions
mérete a szerializálandó típusok számától függ. Ha számos típust – például dinamikusan létrehozott típust – ad át a szerializálónak, a gyorsítótár mérete továbbra is nőni fog, és a végén egy OutOfMemoryException
.
A JsonSerializerOptions.Default
tulajdonság
Ha a használni kívánt példány JsonSerializerOptions
az alapértelmezett példány (az összes alapértelmezett beállítás és az alapértelmezett konverterekkel rendelkezik), használja a JsonSerializerOptions.Default tulajdonságot a beállításpéldány létrehozása helyett. További információ: Az alapértelmezett rendszerkonverter használata.
JsonSerializerOptions másolása
Létezik egy JsonSerializerOptions konstruktor , amely lehetővé teszi, hogy egy új példányt hozzon létre ugyanazokkal a beállításokkal, mint egy meglévő példány, ahogyan az alábbi példában látható:
using System.Text.Json;
namespace CopyOptions
{
public class Forecast
{
public DateTime Date { get; init; }
public int TemperatureC { get; set; }
public string? Summary { get; set; }
};
public class Program
{
public static void Main()
{
Forecast forecast = new()
{
Date = DateTime.Now,
TemperatureC = 40,
Summary = "Hot"
};
JsonSerializerOptions options = new()
{
WriteIndented = true
};
JsonSerializerOptions optionsCopy = new(options);
string forecastJson =
JsonSerializer.Serialize<Forecast>(forecast, optionsCopy);
Console.WriteLine($"Output JSON:\n{forecastJson}");
}
}
}
// Produces output like the following example:
//
//Output JSON:
//{
// "Date": "2020-10-21T15:40:06.8998502-07:00",
// "TemperatureC": 40,
// "Summary": "Hot"
//}
Imports System.Text.Json
Imports System.Text.Json.Serialization
Namespace CopyOptions
Public Class Forecast
Public Property [Date] As Date
Public Property TemperatureC As Integer
Public Property Summary As String
End Class
Public NotInheritable Class Program
Public Shared Sub Main()
Dim forecast1 As New Forecast() With {
.[Date] = Date.Now,
.Summary = Nothing,
.TemperatureC = CType(Nothing, Integer)
}
Dim options As New JsonSerializerOptions() With {
.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault
}
Dim optionsCopy As New JsonSerializerOptions
Dim forecastJson As String = JsonSerializer.Serialize(forecast1, optionsCopy)
Console.WriteLine($"Output JSON:{forecastJson}")
End Sub
End Class
End Namespace
' Produces output like the following example:
'
'Output JSON:
'{
' "Date": "2020-10-21T15:40:06.8998502-07:00",
' "TemperatureC": 40,
' "Summary": "Hot"
'}
A meglévő JsonSerializerOptions
példány metaadat-gyorsítótára nem lesz átmásolva az új példányba. A konstruktor használata tehát nem ugyanaz, mint a meglévő példány újrafelhasználása JsonSerializerOptions
.
A JsonSerializerOptions webes alapértelmezései
Az alábbi beállítások különböző alapértelmezett értékekkel rendelkeznek a webalkalmazásokhoz:
- PropertyNameCaseInsensitive =
true
- JsonNamingPolicy = CamelCase
- NumberHandling = AllowReadingFromString
A .NET 9-ben és újabb verzióiban a JsonSerializerOptions.Web
singleton használatával szerializálhatja azokat az alapértelmezett beállításokat, amelyeket ASP.NET Core használ a webalkalmazásokhoz. A korábbi verziókban hívja meg a JsonSerializerOptions konstruktort , hogy hozzon létre egy új példányt a webes alapértelmezett beállításokkal, ahogyan az alábbi példában látható:
using System.Text.Json;
namespace OptionsDefaults
{
public class Forecast
{
public DateTime? Date { get; init; }
public int TemperatureC { get; set; }
public string? Summary { get; set; }
};
public class Program
{
public static void Main()
{
Forecast forecast = new()
{
Date = DateTime.Now,
TemperatureC = 40,
Summary = "Hot"
};
JsonSerializerOptions options = new(JsonSerializerDefaults.Web)
{
WriteIndented = true
};
Console.WriteLine(
$"PropertyNameCaseInsensitive: {options.PropertyNameCaseInsensitive}");
Console.WriteLine(
$"JsonNamingPolicy: {options.PropertyNamingPolicy}");
Console.WriteLine(
$"NumberHandling: {options.NumberHandling}");
string forecastJson = JsonSerializer.Serialize<Forecast>(forecast, options);
Console.WriteLine($"Output JSON:\n{forecastJson}");
Forecast? forecastDeserialized =
JsonSerializer.Deserialize<Forecast>(forecastJson, options);
Console.WriteLine($"Date: {forecastDeserialized?.Date}");
Console.WriteLine($"TemperatureC: {forecastDeserialized?.TemperatureC}");
Console.WriteLine($"Summary: {forecastDeserialized?.Summary}");
}
}
}
// Produces output like the following example:
//
//PropertyNameCaseInsensitive: True
//JsonNamingPolicy: System.Text.Json.JsonCamelCaseNamingPolicy
//NumberHandling: AllowReadingFromString
//Output JSON:
//{
// "date": "2020-10-21T15:40:06.9040831-07:00",
// "temperatureC": 40,
// "summary": "Hot"
//}
//Date: 10 / 21 / 2020 3:40:06 PM
//TemperatureC: 40
//Summary: Hot
Imports System.Text.Json
Namespace OptionsDefaults
Public Class Forecast
Public Property [Date] As Date
Public Property TemperatureC As Integer
Public Property Summary As String
End Class
Public NotInheritable Class Program
Public Shared Sub Main()
Dim forecast1 As New Forecast() With {
.[Date] = Date.Now,
.TemperatureC = 40,
.Summary = "Hot"
}
Dim options As New JsonSerializerOptions(JsonSerializerDefaults.Web) With {
.WriteIndented = True
}
Console.WriteLine(
$"PropertyNameCaseInsensitive: {options.PropertyNameCaseInsensitive}")
Console.WriteLine(
$"JsonNamingPolicy: {options.PropertyNamingPolicy}")
Console.WriteLine(
$"NumberHandling: {options.NumberHandling}")
Dim forecastJson As String = JsonSerializer.Serialize(forecast1, options)
Console.WriteLine($"Output JSON:{forecastJson}")
Dim forecastDeserialized As Forecast = JsonSerializer.Deserialize(Of Forecast)(forecastJson, options)
Console.WriteLine($"Date: {forecastDeserialized.[Date]}")
Console.WriteLine($"TemperatureC: {forecastDeserialized.TemperatureC}")
Console.WriteLine($"Summary: {forecastDeserialized.Summary}")
End Sub
End Class
End Namespace
' Produces output like the following example:
'
'PropertyNameCaseInsensitive: True
'JsonNamingPolicy: System.Text.Json.JsonCamelCaseNamingPolicy
'NumberHandling: AllowReadingFromString
'Output JSON:
'{
' "date": "2020-10-21T15:40:06.9040831-07:00",
' "temperatureC": 40,
' "summary": "Hot"
'}
'Date: 10 / 21 / 2020 3:40:06 PM
'TemperatureC: 40
'Summary: Hot
Visszajelzés
https://aka.ms/ContentUserFeedback.
Hamarosan elérhető: 2024-ben fokozatosan kivezetjük a GitHub-problémákat a tartalom visszajelzési mechanizmusaként, és lecseréljük egy új visszajelzési rendszerre. További információ:Visszajelzés küldése és megtekintése a következőhöz: