I've got a very strange problem when working with .NET's XmlSerializer
.
Take the following example classes:
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, there are three different methods to solve the InvalidOperationException
that's caused by the serializer not knowing about the derived types of Payment
.
1. Adding XmlInclude
to the Payment
class definition:
This is not possible due to all classes being included as external references over which I have no control of.
2. Passing the derived types' types during creation of the XmlSerializer
instance
Doesn't work.
3. Defining XmlAttributeOverrides
for the target property in order to override the property's default serialization (as explained in this SO post)
Also doesn't work (XmlAttributeOverrides
initialization follows).
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);
The appropriate XmlSerializer
constructor would then be used.
NOTE: by doesn't work I mean the InvalidOperationException
(BankPayment
was not expected...) is thrown.
Can anyone shed some light on the subject? How would one go about and debug the issue further?
This worked for me:
[XmlInclude(typeof(BankPayment))]
[Serializable]
public abstract class Payment { }
[Serializable]
public class BankPayment : Payment {}
[Serializable]
public class Payments : List<Payment>{}
XmlSerializer serializer = new XmlSerializer(typeof(Payments), new Type[]{typeof(Payment)});