JsonSerializerOptions örneklerinin örneğini oluşturma System.Text.Json
Bu makalede, kullanırken JsonSerializerOptionsperformans sorunlarından nasıl kaçınabileceğiniz açıklanmaktadır. Ayrıca, kullanılabilen parametreli oluşturucuların nasıl kullanılacağını da gösterir.
JsonSerializerOptions örneklerini yeniden kullanma
Aynı seçeneklerle tekrar tekrar kullanıyorsanız JsonSerializerOptions
, her kullandığınızda yeni JsonSerializerOptions
bir örnek oluşturmayın. Her çağrı için aynı örneği yeniden kullanma. Bu kılavuz, özel dönüştürücüler için yazdığınız kodlar ve veya JsonSerializer.Deserializeçağrısı JsonSerializer.Serialize yaptığınızda geçerlidir. Aynı örneği birden çok iş parçacığında kullanmak güvenlidir. Seçenekler örneğindeki meta veri önbellekleri iş parçacığı açısından güvenlidir ve ilk serileştirme veya seri durumdan çıkarma işleminden sonra örnek sabittir.
Aşağıdaki kod, yeni seçenek örneklerini kullanmanın performans cezasını gösterir.
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
Yukarıdaki kod, aynı seçenekler örneğini kullanarak küçük bir nesneyi 100.000 kez seri hale getirmektedir. Ardından aynı nesneyi aynı sayıda serileştirir ve her seferinde yeni bir seçenek örneği oluşturur. Tipik bir çalışma süresi farkı 40.140 milisaniyeye kıyasla 190'dır. Yineleme sayısını artırırsanız fark daha da artar.
Seri hale getirici, nesne grafiğindeki her türün ilk seri hale getirilmesi sırasında yeni bir seçenek örneği geçirildiğinde bir ısınma aşamasından geçer. Bu ısınma, serileştirme için gereken meta verilerin önbelleğini oluşturmayı içerir. Meta veriler özellik alıcıları, ayarlayıcılar, oluşturucu bağımsız değişkenleri, belirtilen öznitelikler vb. için temsilciler içerir. Bu meta veri önbelleği seçenekler örneğinde depolanır. Aynı ısınma işlemi ve önbellek seri durumdan çıkarma için de geçerlidir.
Bir JsonSerializerOptions
örnekteki meta veri önbelleğinin boyutu, serileştirilecek tür sayısına bağlıdır. Seri hale getiriciye çok sayıda tür (örneğin, dinamik olarak oluşturulan türler) geçirirseniz, önbellek boyutu büyümeye devam eder ve bir OutOfMemoryException
'e neden olabilir.
özelliği JsonSerializerOptions.Default
Kullanmanız gereken örneği JsonSerializerOptions
varsayılan örnekse (tüm varsayılan ayarlara ve varsayılan dönüştürücülere sahiptir), bir seçenek örneği oluşturmak yerine özelliğini kullanın JsonSerializerOptions.Default . Daha fazla bilgi için bkz . Varsayılan sistem dönüştürücüsü kullanma.
JsonSerializerOptions Kopyalama
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"
'}
Mevcut JsonSerializerOptions
örneğin meta veri önbelleği yeni örneğe kopyalanır. Bu nedenle bu oluşturucuyu kullanmak, var olan bir örneğini yeniden kullanmakla JsonSerializerOptions
aynı değildir.
JsonSerializerOptions için web varsayılanları
Aşağıdaki seçenekler web uygulamaları için farklı varsayılanlara sahiptir:
- PropertyNameCaseInsensitive =
true
- PropertyNamingPolicy = CamelCase
- NumberHandling = AllowReadingFromString
.NET 9 ve sonraki sürümlerde, ASP.NET Core'un web uygulamaları için kullandığı varsayılan seçeneklerle seri hale getirmek için singleton kullanabilirsiniz JsonSerializerOptions.Web
. Önceki sürümlerde, aşağıdaki örnekte gösterildiği gibi web varsayılanlarıyla yeni bir örnek oluşturmak için JsonSerializerOptions oluşturucuyu çağırın:
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