Seri durumdan çıkarma davranışını özelleştirme
JsonSerializer.Deserialize yöntemi, JavaScript Nesne Gösterimi (JSON) dizesini bir C# nesnesine geri dönüştürmek için kullanılır. Seri durumdan çıkarma, JSON dosyalarını okurken, API'lerden JSON verileri alırken veya JSON verilerinin genel işlenmesinde kullanılır.
Deserialize yöntemi bir JSON dizesini ve giriş olarak oluşturulacak nesnenin türünü alır ve bu nesnenin bir örneğini döndürür.
Aşağıdaki kod, kullanarak JsonSerializer.Deserializebir JSON dizesini bir nesneye geri dönüştürmeyi gösterir:
string jsonString = """{"Name":"Anette Thomsen","Age":30,"Address":"123 Main St"}""";
var customer = JsonSerializer.Deserialize<Employee>(jsonString);
Seri durumdan çıkarma davranışı
Serileştirme gibi seri durumdan çıkarma da bazı varsayılan davranışları izler. JSON seri durumdan çıkarılırken aşağıdaki davranışlar geçerlidir:
- Varsayılan olarak, özellik adı eşleştirme büyük/küçük harfe duyarlıdır. Büyük/küçük harfe duyarsızlığı belirtebilirsiniz.
- Ortak olmayan oluşturucular seri hale getirici tarafından yoksayılır.
- Ortak küme erişimcileri olmayan sabit nesnelere veya özelliklere seri durumdan çıkarma desteklenir ancak varsayılan olarak etkinleştirilmez. Bkz. Sabit türler ve kayıtlar.
- Sabit listeleri varsayılan olarak sayı olarak desteklenir. Dize sabit listesi alanlarını seri durumdan çıkarabilirsiniz.
- Varsayılan olarak alanlar yoksayılır. Alanları ekleyebilirsiniz.
- Varsayılan olarak, JSON içindeki açıklamalar veya sondaki virgüller özel durumlar oluşturur. Açıklamalara ve sondaki virgüllere izin vekleyebilirsiniz.
- Varsayılan maksimum derinlik 64'dür.
JsonSerializerOptions kullanarak seri durumdan çıkarma davranışını özelleştirme
sınıfı, JsonSerializerOptions yönteminin seri durumdan çıkarma davranışını JsonSerializer.Deerialize özelleştirmenize olanak tanır.
Bu ünitede aşağıdaki özellikler gösterilmiştir:
-
RespectRequiredConstructorParameters: Bu özellik, JSON seri durumdan çıkarma için isteğe bağlı olmayan tüm oluşturucu parametrelerinin gerekli olup olmadığını belirtir. -
PreferredObjectCreationHandling: Bu özellik, seri durumdan çıkarma sırasında tercih edilen nesne oluşturma işleme davranışını belirtir.
Seri durumdan çıkarma özelliğini özelleştirmek için yaygın olarak kullanılan diğer özellikler şunlardır:
-
Converters: Bu özellik, belirli türleri veya karmaşık nesneleri işlemek için özel dönüştürücüler eklemenize olanak tanır. Örneğin, iç içe nesneler veya karmaşık özellikler içeren bir sınıf için özel dönüştürücü oluşturabilirsiniz. -
DefaultBufferSize: Bu özellik, büyük JSON dizelerini veya UTF-8 bayt dizilerini seri durumdan çıkarırken performansı geliştirebilen varsayılan arabellek boyutunu bayt cinsinden ayarlar. -
AllowTrailingCommas: Bu özellik JSON dizilerinde ve nesnelerinde sondaki virgüllere izin verir. Bu, sondaki virgüllere sahip olabilecek JSON verileriyle ilgilenirken yararlı olabilir. -
AllowOutOfOrderMetadataProperties: Bu özellik, ve$idgibi$typeJSON meta veri özelliklerinin seri durumdan çıkarılmış JSON nesnesinin en başında belirtilmesi gereksinimini kaldırır. -
NumberHandling: Bu özellik, seri hale getirildiğinde veya seri durumdan çıkarılırken sayı türlerinin nasıl işleneceğini belirtir. Bu, sayısal değerlerin doğru gösterimini sağlamak için yararlı olabilir.
Gerekli özellikleri seri durumdan çıkarma
Seri durumdan çıkarmanın başarılı olması için JSON yükünde bulunmaları gerektiğini göstermek için belirli özellikleri işaretleyebilirsiniz. Benzer şekilde, isteğe bağlı olmayan tüm oluşturucu parametrelerinin JSON yükünde mevcut olduğunu belirtmek için bir seçenek ayarlayabilirsiniz. Bu gerekli özelliklerden biri veya daha fazlası yoksa, JsonSerializer.Deserialize yöntemler bir JsonExceptionoluşturur.
JSON seri durumdan çıkarma için bir özelliği veya alanı gerektiği gibi işaretlemenin üç yolu vardır:
- Değiştiriciyi
requiredekleyerek. - ile
JsonRequiredAttributeek açıklama ekleyerek. - Sözleşme modelinin
JsonPropertyInfo.IsRequiredözelliğini değiştirerek.
JSON seri durumdan çıkarma için isteğe bağlı olmayan tüm oluşturucu parametrelerinin gerekli olduğunu belirtmek için seçeneğini olarak JsonSerializerOptions.RespectRequiredConstructorParametersayarlayıntrue.
Seri hale getiricinin perspektifinden, C# required değiştiricisi ve [JsonRequired] özniteliği eşdeğerdir ve her ikisi de aynı meta veri parçası olan ile eşlenir JsonPropertyInfo.IsRequired. Çoğu durumda yerleşik C# anahtar sözcüğünü kullanırsınız. Ancak, aşağıdaki durumlarda bunun yerine kullanmanız JsonRequiredAttribute gerekir:
- C# dışında bir programlama dili veya C# 'nin alt düzey bir sürümünü kullanıyorsanız.
- Gereksinimin yalnızca JSON seri durumdan çıkarma işlemine uygulanmasını istiyorsanız.
- Kaynak oluşturma modunda serileştirme kullanıyorsanız
System.Text.Json. Bu durumda, kaynak oluşturma işlemi derleme zamanında gerçekleştiğinden gerekli değiştiriciyi kullanırsanız kodunuz derlenmez.
Aşağıdaki kod parçacığında anahtar sözcüğüyle değiştirilen bir özellik örneği gösterilmektedir required . Seri durumdan çıkarmanın başarılı olması için bu özelliğin JSON yükünde mevcut olması gerekir.
public static void RunIt()
{
// The following line throws a JsonException at run time.
Console.WriteLine(JsonSerializer.Deserialize<Person>("""{"Age": 42}"""));
}
public class Person
{
public required string Name { get; set; }
public int Age { get; set; }
}
Alternatif olarak, kullanabilirsiniz JsonRequiredAttribute:
public static void RunIt()
{
// The following line throws a JsonException at run time.
Console.WriteLine(JsonSerializer.Deserialize<Person>("""{"Age": 42}"""));
}
public class Person
{
[JsonRequired]
public string Name { get; set; }
public int Age { get; set; }
}
Ayrıca, özelliğini kullanarak JsonPropertyInfo.IsRequired sözleşme modeli aracılığıyla bir özelliğin gerekli olup olmadığını denetlemek de mümkündür:
public static void RunIt()
{
var options = new JsonSerializerOptions
{
TypeInfoResolver = new DefaultJsonTypeInfoResolver
{
Modifiers =
{
static typeInfo =>
{
if (typeInfo.Kind != JsonTypeInfoKind.Object)
return;
foreach (JsonPropertyInfo propertyInfo in typeInfo.Properties)
{
// Strip IsRequired constraint from every property.
propertyInfo.IsRequired = false;
}
}
}
}
};
// Deserialization succeeds even though
// the Name property isn't in the JSON payload.
JsonSerializer.Deserialize<Person>("""{"Age": 42}""", options);
}
public class Person
{
public required string Name { get; set; }
public int Age { get; set; }
}
Başlatılan özellikleri seri durumdan çıkarma ve doldurma
Bir JSON dizesini bir nesneye seri durumdan çıkarırken, belirli özelliklerin başlatılıp başlatılmayacağını belirtebilirsiniz. Bu, seri durumdan çıkarılmış nesnenin kullanılmadan önce gerekli tüm verilere sahip olduğundan emin olmak için kullanışlıdır.
.NET 8'den başlayarak, JSON seri durumdan çıkarıldığında .NET özelliklerini değiştirmek veya doldurmak için bir tercih belirtebilirsiniz.
JsonObjectCreationHandling sabit listesi, nesne oluşturma işleme seçeneklerini sağlar:
-
JsonObjectCreationHandling.Replace: Varsayılan davranış. Özellikler JSON yükündeki değerlerle değiştirilir. Bu, .NET'in önceki sürümlerindekiyle aynı davranıştır. -
JsonObjectCreationHandling.Populate: Özellikler JSON yükündeki değerlerle doldurulur. Bu, bir özelliğin zaten başlatılmış olması durumunda değerinin JSON yükündeki değerle güncelleştirildiğini gösterir.
Varsayılan (değiştirme) davranışı
Seri System.Text.Json durumdan çıkarıcı her zaman hedef türün yeni bir örneğini oluşturur. Ancak, yeni bir örnek oluşturulsa bile, bazı özellikler ve alanlar nesnenin yapımının bir parçası olarak zaten başlatılmış olabilir. Aşağıdaki türü göz önünde bulundurun:
class A
{
public List<int> Numbers1 { get; } = [1, 2, 3];
public List<int> Numbers2 { get; set; } = [1, 2, 3];
}
Bu sınıfın bir örneğini oluşturduğunuzda, iki List tür özelliği üç öğeyle (1, 2 ve 3) başlatılır. JSON'un serisini bu türe kaldırırsanız, varsayılan davranış özellik değerlerini JSON yükündeki verilerle değiştirmektir.
- için
Numbers1salt okunur olduğundan (ayarlayıcı olmadığından), listesinde hala 1, 2 ve 3 değerleri vardır. - okuma-yazma
Numbers2olan için yeni bir liste ayrılır ve JSON'dan değerler eklenir.
Örneğin, aşağıdaki seri durumdan çıkarma kodunu yürütürseniz, 1, Numbers1 2 ve 3 değerlerini ve 4, 5 ve Numbers2 6 değerlerini içerir.
var json = """{"Numbers1": [4, 5, 6], "Numbers2": [4, 5, 6]}""";
var a = JsonSerializer.Deserialize<A>(json);
Console.WriteLine(string.Join(", ", a.Numbers1));
Console.WriteLine(string.Join(", ", a.Numbers2));
// Output: 1, 2, 3
// Output: 4, 5, 6
Doldurma davranışı
Seri durumdan çıkarma davranışını değiştirmek yerine özellikleri ve alanları değiştirmek (doldurmak) için değiştirebilirsiniz:
- Koleksiyon türü özelliği için nesne temizlenmeden yeniden kullanılır. Koleksiyon öğelerle önceden doldurulmuşsa, seri durumdan çıkarılmış son sonuçta JSON değerleriyle birlikte gösterilir.
- Özellikleri olan bir nesne olan bir özellik için, değiştirilebilir özellikleri JSON değerlerine güncelleştirilir, ancak nesne başvurusunun kendisi değişmez.
- Yapı türü özelliği için etkili davranış, değiştirilebilir özellikleri için mevcut değerlerin tutulması ve JSON'dan yeni değerlerin eklenmesidir. Ancak, bir başvuru özelliğinden farklı olarak, nesnenin kendisi bir değer türü olduğundan yeniden kullanılmaz. Bunun yerine, yapının bir kopyası değiştirilir ve ardından özelliğine yeniden atanır.
Bir struct özelliğin ayarlayıcısı olmalıdır; aksi takdirde, çalışma zamanında bir InvalidOperationException oluşturulur.
Önemli
Davranış Populate şu anda parametreli oluşturucuya sahip türler için çalışmıyor.
Nasıl belirtilir?
veya replaceiçin populate bir tercih belirtmenin birden çok yolu vardır:
JsonObjectCreationHandlingAttributetür veya özellik düzeyinde açıklama eklemek için özniteliğini kullanın. Özniteliği tür düzeyinde ayarlar ve özelliğiniHandlingolarak ayarlarsanızPopulate, davranış yalnızca popülasyonu mümkün olan özellikler için geçerlidir (örneğin, değer türlerinin bir ayarlayıcıya sahip olması gerekir).Tür genelinde tercihin olmasını
Populateistiyorsanız ancak bu davranıştan bir veya daha fazla özelliği dışlamak istiyorsanız, devralınan davranışı geçersiz kılmak için özniteliği tür düzeyinde ve özellik düzeyinde yeniden ekleyebilirsiniz. Bu düzen aşağıdaki kodda gösterilmiştir.// Type-level preference is Populate. [JsonObjectCreationHandling(JsonObjectCreationHandling.Populate)] class B { // For this property only, use Replace behavior. [JsonObjectCreationHandling(JsonObjectCreationHandling.Replace)] public List<int> Numbers1 { get; } = [1, 2, 3]; public List<int> Numbers2 { get; set; } = [1, 2, 3]; }Genel bir tercih belirtmek için ayarlayın
JsonSerializerOptions.PreferredObjectCreationHandling.var options = new JsonSerializerOptions { PreferredObjectCreationHandling = JsonObjectCreationHandling.Populate };
JSON dosyalarını okuma
kullanarak File.ReadAllTextJSON dosyalarını okuma.
using System;
using System.IO;
using System.Text.Json;
class Program
{
static void Main()
{
string jsonString = File.ReadAllText("customer.json");
var customer = JsonSerializer.Deserialize<BankCustomer>(jsonString);
Console.WriteLine($"Name: {customer.Name}, Age: {customer.Age}, Address: {customer.Address}");
}
}
Özet
Bu ünitede, yöntemini kullanarak JSON verilerini C# nesnelerine seri durumdan çıkarırken varsayılan seri durumdan çıkarma davranışını özelleştirmeyi JsonSerializer.Deserialize öğrendiniz. Varsayılan davranışlar, özellikleri gerekli olarak işaretleme ve seri durumdan çıkarma sırasında özelliklerin değiştirilmesi veya doldurulması gerekip gerekmediğini belirtme hakkında bilgi edinmişsinizdir. Son olarak kullanarak JSON dosyalarını File.ReadAllTextokumayı öğrendinsiniz.