Saya mendapat masalah yang sangat aneh saat bekerja dengan .NET XmlSerializer
.
Ambil kelas contoh berikut:
public class Order
{
public PaymentCollection Payments { get; set; }
//everything else is serializable (including other collections of non-abstract types)
}
public class PaymentCollection : Collection<Payment>
{
}
public abstract class Payment
{
//abstract methods
}
public class BankPayment : Payment
{
//method implementations
}
AFAIK, ada tiga metode berbeda untuk menyelesaikannya InvalidOperationException
yang disebabkan oleh serializer tidak mengetahui tentang jenis turunannya Payment
.
1. Menambahkan XmlInclude
ke Payment
definisi kelas:
Ini tidak mungkin karena semua kelas dimasukkan sebagai referensi eksternal yang tidak dapat saya kendalikan.
2. Meneruskan tipe turunan selama pembuatan XmlSerializer
instance
Tidak berhasil.
3. Mendefinisikan XmlAttributeOverrides
properti target untuk menimpa serialisasi default properti (seperti yang dijelaskan dalam posting SO ini )
Juga tidak berfungsi ( XmlAttributeOverrides
inisialisasi mengikuti).
Type bankPayment = typeof(BankPayment);
XmlAttributes attributes = new XmlAttributes();
attributes.XmlElements.Add(new XmlElementAttribute(bankPayment.Name, bankPayment));
XmlAttributeOverrides overrides = new XmlAttributeOverrides();
overrides.Add(typeof(Order), "Payments", attributes);
XmlSerializer
Konstruktor yang sesuai kemudian akan digunakan.
CATATAN: dengan tidak bekerja maksud saya InvalidOperationException
( BankPayment
tidak diharapkan ... ) dilemparkan.
Adakah yang bisa menjelaskan subjek ini? Bagaimana cara men-debug masalah lebih lanjut?
sumber
Baru saja menyelesaikan masalah. Setelah menggali beberapa saat lagi, saya menemukan posting SO ini yang mencakup situasi yang sama persis. Itu membuat saya di jalur yang benar.
Pada dasarnya,
XmlSerializer
kebutuhan untuk mengetahui namespace default jika kelas turunan disertakan sebagai tipe tambahan. Alasan pasti mengapa ini harus terjadi masih belum diketahui tetapi, tetap saja, serialisasi berfungsi sekarang.sumber
Saya setuju dengan bizl
juga jika Anda perlu menerapkan kelas yang disertakan ini ke item objek, Anda dapat melakukan seperti itu
sumber
Lakukan saja di Base, dengan cara itu setiap anak dapat berseri, lebih sedikit kode pembersih kode.
Dengan cara ini Anda dapat memanggil Serialize pada kelas anak tidak peduli situasinya dan masih dapat melakukan apa yang Anda butuhkan sebelum objek berseri.
sumber
Berdasarkan ini saya dapat menyelesaikan ini dengan mengubah konstruktor yang
XmlSerializer
saya gunakan alih-alih mengubah kelas.Alih-alih menggunakan sesuatu seperti ini (disarankan di jawaban lain):
Saya melakukan ini:
sumber