Mam bardzo dziwny problem podczas pracy z .NET XmlSerializer
.Użyj atrybutu XmlInclude lub SoapInclude, aby określić typy nieznane statycznie
podjąć następujące przykładowe zajęcia:
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, istnieją trzy różne sposoby, aby rozwiązać ten InvalidOperationException
że to spowodowane serializer nie wiedząc o pochodnych typów Payment
.
1. Dodanie XmlInclude
definicji Payment
klasy:
Nie jest to możliwe ze względu na wszystkie zajęcia zostały ujęte jako odniesień zewnętrznych, nad którymi nie mam kontroli.
2. Przechodząc rodzajów rodzajów drewna podczas tworzenia instancji XmlSerializer
nie działa.
3. Definiowanie XmlAttributeOverrides
dla właściwości docelowej, aby zastąpić domyślne serializacji na własność (jak wyjaśniono w this SO post)
również nie działa (XmlAttributeOverrides
inicjalizacji poniżej).
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);
Zostanie wówczas użyty odpowiedni konstruktor XmlSerializer
.
UWAGA: przez nie działa Znaczy InvalidOperationException
(BankPayment
nie oczekiwano ...) jest rzucony.
Czy ktoś może rzucić nieco światła na ten temat? W jaki sposób obejść i dalej debugować problem?
Więc typ bazowy musi znać wszystkie jego implementacje? To nie wydaje się być bardzo dobrym rozwiązaniem. Czy nie ma innej drogi? –
@AlexanderStolz do ogólnej implementacji przekazującej nowy typ podczas tworzenia obiektu XmlSerializable jest najlepszym rozwiązaniem. Jak wspomniano http://stackoverflow.com/a/2689660/698127 – Aamol