Tengo un problema muy extraño al trabajar con .NET XmlSerializer.
Tome las siguientes clases de ejemplo:
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, hay tres métodos diferentes para resolver el problema InvalidOperationExceptioncausado por el serializador que no conoce los tipos derivados de Payment.
1. Añadiendo XmlIncludea la Paymentdefinición de clase:
Esto no es posible debido a que todas las clases se incluyen como referencias externas sobre las que no tengo control.
2. Pasar los tipos de tipos derivados durante la creación de la XmlSerializerinstancia
No funciona.
3. Definición XmlAttributeOverridesde la propiedad de destino para anular la serialización predeterminada de la propiedad (como se explica en esta publicación SO )
Tampoco funciona ( XmlAttributeOverridessigue la inicialización).
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);
XmlSerializerEntonces se usaría el constructor apropiado .
NOTA: por no funciona me refiero a que se lanza InvalidOperationException( BankPaymentno se esperaba ... ).
¿Alguien puede arrojar algo de luz sobre el tema? ¿Cómo se procedería a depurar más el problema?
fuente

Acabo de resolver el problema. Después de investigar un poco más, encontré esta publicación SO que cubre exactamente la misma situación. Me puso en el camino correcto.
Básicamente, es
XmlSerializernecesario conocer el espacio de nombres predeterminado si las clases derivadas se incluyen como tipos adicionales. La razón exacta por la que esto tiene que suceder aún se desconoce, pero, aún así, la serialización está funcionando ahora.fuente
Estoy de acuerdo con bizl
Además, si necesita aplicar esta clase incluida a un elemento de objeto, puede hacerlo así
fuente
Simplemente hágalo en la Base, de esa manera cualquier niño puede ser serializado, menos código limpiador de código.
De esta manera, puede llamar a Serialize en la clase secundaria sin importar las circunstancias y aún así poder hacer lo que necesita antes de que el objeto Serialize.
fuente
En base a esto , pude resolver esto cambiando el constructor
XmlSerializerque estaba usando en lugar de cambiar las clases.En lugar de usar algo como esto (sugerido en las otras respuestas):
Hice esto:
fuente