Ich habe ein sehr seltsames Problem bei der Arbeit mit .NETs XmlSerializer
.
Nehmen Sie die folgenden Beispielklassen:
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, es gibt drei verschiedene Methoden, um das Problem zu lösen InvalidOperationException
, das dadurch verursacht wird, dass der Serializer die abgeleiteten Typen von nicht kennt Payment
.
1. Hinzufügen XmlInclude
zur Payment
Klassendefinition:
Dies ist nicht möglich, da alle Klassen als externe Referenzen enthalten sind, über die ich keine Kontrolle habe.
2. Übergeben der Typen der abgeleiteten Typen während der Erstellung der XmlSerializer
Instanz
Funktioniert nicht
3. Definieren XmlAttributeOverrides
der Zieleigenschaft, um die Standardserialisierung der Eigenschaft zu überschreiben (wie in diesem SO-Beitrag erläutert ).
Funktioniert auch nicht ( XmlAttributeOverrides
Initialisierung folgt).
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);
Der entsprechende XmlSerializer
Konstruktor würde dann verwendet.
HINWEIS: Mit funktioniert nicht Ich meine, das InvalidOperationException
( BankPayment
wurde nicht erwartet ... ) wird geworfen.
Kann jemand etwas Licht in das Thema bringen? Wie würde man vorgehen und das Problem weiter debuggen?
quelle
Habe gerade das Problem gelöst. Nachdem ich eine Weile länger herumgegraben hatte, fand ich diesen SO-Beitrag , der genau die gleiche Situation abdeckt. Es hat mich auf den richtigen Weg gebracht.
Grundsätzlich
XmlSerializer
muss der Standard-Namespace bekannt sein, wenn abgeleitete Klassen als zusätzliche Typen enthalten sind. Der genaue Grund, warum dies geschehen muss, ist noch unbekannt, aber die Serialisierung funktioniert derzeit noch.quelle
Ich stimme bizl zu
Auch wenn Sie diese enthaltene Klasse auf ein Objektelement anwenden müssen, können Sie dies tun
quelle
Tun Sie es einfach in der Basis, auf diese Weise kann jedes Kind serialisiert werden, weniger Code-Cleaner-Code.
Auf diese Weise können Sie Serialize für die untergeordnete Klasse aufrufen, unabhängig von den Umständen, und trotzdem das tun, was Sie benötigen, bevor das Objekt Serializes ausgeführt wird.
quelle
Auf dieser Grundlage konnte ich dieses Problem lösen, indem
XmlSerializer
ich den von mir verwendeten Konstruktor änderte , anstatt die Klassen zu ändern.Anstatt so etwas zu verwenden (in den anderen Antworten vorgeschlagen):
Ich war das:
quelle