Inicializált tulajdonságok feltöltése
A .NET 8-tól kezdve megadhatja, hogy a JSON deszerializálásakor a .NET-tulajdonságokat cserélje le vagy töltse fel . Az JsonObjectCreationHandling enumerálás biztosítja az objektumlétrehozási kezelési lehetőségeket:
Alapértelmezett (csere) viselkedés
A System.Text.Json deszerializáló mindig létrehoz egy új példányt a céltípushoz. Annak ellenére, hogy új példány jön létre, előfordulhat, hogy egyes tulajdonságok és mezők már inicializálva vannak az objektum konstrukciójának részeként. Vegye figyelembe a következő típust:
class A
{
public List<int> Numbers1 { get; } = [1, 2, 3];
public List<int> Numbers2 { get; set; } = [1, 2, 3];
}
Az osztály egy példányának létrehozásakor a Numbers1
(és Numbers2
) tulajdonság értéke egy három elemet (1, 2 és 3) tartalmazó lista. Ha a JSON-t ilyen típusúra deszerializálja, az alapértelmezett viselkedés az, hogy a tulajdonságértékek lecserélődnek:
- Mivel
Numbers1
írásvédett (nincs beállító), továbbra is az 1, a 2 és a 3 érték szerepel a listában. - Az olvasási-írási értékhez
Numbers2
egy új lista lesz lefoglalva, és hozzáadja a JSON-ból származó értékeket.
Ha például a következő deszerializálási kódot hajtja végre, az 1, Numbers1
a 2 és a 3 értéket, valamint Numbers2
a 4, 5 és 6 értéket tartalmazza.
A? a = JsonSerializer.Deserialize<A>("""{"Numbers1": [4,5,6], "Numbers2": [4,5,6]}""");
Viselkedés feltöltése
A .NET 8-tól kezdve a deszerializálási viselkedést módosíthatja a tulajdonságok és mezők módosítása (feltöltése) helyett:
Gyűjtemény típusú tulajdonság esetén az objektum törlés nélkül újra felhasználható. Ha a gyűjtemény előre feltöltve van elemekkel, akkor a végső deszerializált eredményben jelennek meg a JSON értékeivel együtt. Példaként lásd a Gyűjtemény tulajdonság példáját.
A tulajdonsággal rendelkező objektumok esetében a rendszer frissíti a változó tulajdonságait a JSON-értékekre, de maga az objektumhivatkozás nem változik.
A struct típusú tulajdonság esetében a tényleges viselkedés az, hogy a rendszer megőrzi a meglévő értékeket, és új értékeket ad hozzá a JSON-ból. A referenciatulajdonságokkal ellentétben azonban maga az objektum nem lesz újra felhasználva, mivel értéktípus. Ehelyett a rendszer módosítja a szerkezet egy példányát, majd újból hozzárendeli a tulajdonsághoz. Példaként lásd a Struct tulajdonság példáját.
A szerkezettulajdonságoknak elválasztóval kell rendelkezniük; ellenkező esetben a InvalidOperationException rendszer futásidőben dob.
Feljegyzés
A feltöltési viselkedés jelenleg nem működik paraméteres konstruktort tartalmazó típusok esetében. További információ: dotnet/runtime issue 92877.
Csak olvasható tulajdonságok
A nem módosítható referenciatulajdonságok feltöltéséhez, mivel a tulajdonsághivatkozásokat tartalmazó példányt nem cseréli le, a tulajdonságnak nem kell beállítóval rendelkeznie. Ez a viselkedés azt jelenti, hogy a deszerializálás írásvédett tulajdonságokat is feltölthet.
Feljegyzés
A szerkezettulajdonságokhoz továbbra is szükség van a beállítókra, mert a példányt módosított másolatra cseréli a rendszer.
Példa gyűjteménytulajdonságra
Vegye figyelembe ugyanezt az osztályt A
a helyettesítési viselkedési példában, de ezúttal ahelyett, hogy lecserélné őket, az előugró tulajdonságokat részesíti előnyben:
[JsonObjectCreationHandling(JsonObjectCreationHandling.Populate)]
class A
{
public List<int> Numbers1 { get; } = [1, 2, 3];
public List<int> Numbers2 { get; set; } = [1, 2, 3];
}
Ha a következő deszerializálási kódot hajtja végre, az Numbers2
1, Numbers1
2, 3, 4, 5 és 6 értéket tartalmazza:
A? a = JsonSerializer.Deserialize<A>("""{"Numbers1": [4,5,6], "Numbers2": [4,5,6]}""");
Példa a Struct tulajdonságra
Az alábbi osztály tartalmaz egy struct tulajdonságot, S1
amelynek deszerializálási viselkedése a következőre Populatevan állítva. A kód c.S1.Value1
végrehajtása után a kód értéke 10 (a konstruktorból), és c.S1.Value2
értéke 5 (a JSON-ból).
C? c = JsonSerializer.Deserialize<C>("""{"S1": {"Value2": 5}}""");
class C
{
public C()
{
_s1 = new S
{
Value1 = 10
};
}
private S _s1;
[JsonObjectCreationHandling(JsonObjectCreationHandling.Populate)]
public S S1
{
get { return _s1; }
set { _s1 = value; }
}
}
struct S
{
public int Value1 { get; set; }
public int Value2 { get; set; }
}
Ha ehelyett az alapértelmezett Replace viselkedést használná, c.S1.Value1
az alapértelmezett értéke 0 lenne a deszerializálás után. Ennek az az oka, c.S1.Value1
hogy a konstruktor C()
neve 10 lesz, de az S1 értékét lecseréli egy új példányra. (c.S1.Value2
továbbra is 5, mivel a JSON az alapértelmezett értéket helyettesíti.)
A beállítás menete
A csere vagy feltöltés beállításának többféle módja is van:
JsonObjectCreationHandlingAttribute Az attribútummal a típus vagy a tulajdonság szintjén jegyzetelhet. Ha az attribútumot a típus szintjén állítja be, és annak tulajdonságát Populateállítja Handling be, a viselkedés csak azokra a tulajdonságokra lesz érvényes, amelyekben a sokaság lehetséges (például az értéktípusoknak elválasztóval kell rendelkezniük).
Ha azt szeretné, hogy a típusszintű beállítás legyen Populate, de ki szeretne zárni egy vagy több tulajdonságot ebből a viselkedésből, az örökölt viselkedés felülbírálása érdekében hozzáadhatja az attribútumot a típus szintjén, majd ismét a tulajdonság szintjén. Ez a minta az alábbi kódban jelenik meg.
// 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]; }
Állítsa be JsonSerializerOptions.PreferredObjectCreationHandling (vagy a forrásgeneráláshoz JsonSourceGenerationOptionsAttribute.PreferredObjectCreationHandling) a globális beállítások megadásához.
var options = new JsonSerializerOptions { PreferredObjectCreationHandling = JsonObjectCreationHandling.Populate };
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: