Share via


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

Aşağıdaki örnekte gösterildiği gibi mevcut bir örnekle aynı seçeneklere sahip yeni bir örnek oluşturmanıza olanak tanıyan bir JsonSerializerOptions oluşturucu vardır:

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 JsonSerializerOptionsaynı değildir.

JsonSerializerOptions için web varsayılanları

Aşağıdaki seçenekler web uygulamaları için farklı varsayılanlara sahiptir:

.NET 9 ve sonraki sürümlerinde, 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