Bagikan melalui


XmlSerializer tidak lagi mengabaikan properti yang ditandai dengan ObsoleteAttribute

Mulai dari .NET 10, perilaku XmlSerializer telah berubah sehubungan dengan cara menangani properti yang ditandai dengan ObsoleteAttribute atribut . Sebelumnya, properti yang ditandai dengan [Obsolete] diperlakukan seolah-olah juga ditandai dengan [XmlIgnore], menyebabkannya dikecualikan dari serialisasi XML. Perilaku ini tidak diinginkan dan telah dikoreksi.

Dengan perubahan ini, properti yang ditandai dengan [Obsolete] sekarang diserialisasikan secara default kecuali IsError properti diatur ke true. Jika IsError adalah true, serializer melempar InvalidOperationException selama proses pembuatan. Selain itu, sakelar AppContext, Switch.System.Xml.IgnoreObsoleteMembers, telah diperkenalkan untuk memungkinkan pengembang kembali ke perilaku sebelumnya, jika perlu.

Versi yang diperkenalkan

.NET 10

Perilaku sebelumnya

Dalam versi .NET sebelumnya, properti yang ditandai dengan [Obsolete] atribut dikecualikan dari serialisasi XML, mirip dengan properti yang ditandai dengan [XmlIgnore]. Perilaku ini tidak terduga dan tidak selaras dengan tujuan [Obsolete] atribut yang dimaksudkan, yaitu memberikan peringatan waktu kompilasi tentang API yang tidak digunakan lagi.

public class Example
{
    public string NormalProperty { get; set; } = "normal";

    [Obsolete("This property is deprecated")]
    public string ObsoleteProperty { get; set; } = "obsolete";

    [XmlIgnore]
    public string IgnoredProperty { get; set; } = "ignored";
}

var obj = new Example();
var serializer = new XmlSerializer(typeof(Example));
using var writer = new StringWriter();
serializer.Serialize(writer, obj);
Console.WriteLine(writer.ToString());

Output sebelum perubahan:

<Example>
  <NormalProperty>normal</NormalProperty>
</Example>

Perilaku baru

Mulai dari .NET 10, properti yang ditandai dengan [Obsolete] tidak lagi dikecualikan dari serialisasi XML secara default. Sebaliknya:

  • [Obsolete] Jika atribut diterapkan dengan IsError = false (default), properti diserialisasikan secara normal.
  • Jika atribut [Obsolete] diterapkan dengan IsError = true, maka XmlSerializer akan melemparkan InvalidOperationException saat pembuatan serializer.

Menggunakan kode yang sama seperti yang ditunjukkan di bagian perilaku sebelumnya, output setelah perubahan adalah:

<Example>
  <NormalProperty>normal</NormalProperty>
  <ObsoleteProperty>obsolete</ObsoleteProperty>
</Example>

Jika [Obsolete(IsError = true)] diterapkan ke properti, pengecualian berikut dilemparkan selama pembuatan serializer:

System.InvalidOperationException: Tidak dapat membuat serial anggota 'ObsoleteProperty' karena ditandai dengan ObsoleteAttribute dan IsError diatur ke true.

Nota

Properti yang ditandai sebagai [Obsolete] selalu berhasil dideserialisasi saat data ada di XML. Meskipun perubahan ini memungkinkan [Obsolete] properti untuk "pulang pergi" dari objek ke XML dan kembali ke objek, perilaku baru hanya memengaruhi setengah serialisasi (objek ke XML) dari "pulang pergi."

Jenis perubahan yang memutus kompatibilitas

Perubahan ini adalah perubahan perilaku.

Alasan perubahan

Perilaku sebelumnya memperlakukan [Obsolete] setara dengan [XmlIgnore] tidak diinginkan dan tidak konsisten dengan tujuan [Obsolete] atribut. Perubahan ini memastikan bahwa [Obsolete] hanya digunakan untuk tujuan yang dimaksudkan untuk memberikan peringatan waktu kompilasi dan tidak memengaruhi perilaku serialisasi runtime. Pengenalan sakelar AppContext memungkinkan pengembang untuk ikut serta dalam perilaku warisan jika perlu.

Tinjau ulang kode Anda untuk mengidentifikasi ketergantungan pada perilaku sebelumnya di mana properti [Obsolete] dikecualikan dari serialisasi XML. Jika perilaku ini masih diinginkan, aktifkan sakelar Switch.System.Xml.IgnoreObsoleteMembers AppContext sebagai berikut:

AppContext.SetSwitch("Switch.System.Xml.IgnoreObsoleteMembers", true);

Jika ada properti yang ditandai dengan [Obsolete(IsError = true)] dan sedang diserialisasikan, perbarui kode untuk menghapus [Obsolete] atribut atau mengatur IsError = false untuk menghindari pengecualian runtime.

API yang terpengaruh