Fehler bei Serialialisierung/Deserialisierung von List<> mit XmlSerializer via Reflection
-
Hallo Zusammen,
Ich habe da ein Problem. Ich binde zur Laufzeit einer Anwendung .dlls dynamisch mit Hilfe von Reflection ein. Das funktioniert auch einwandfrei.
In einer der eingebundenen .dlls werden nun Objekte mit Hilfe eines XmlSerializers in XML Form gebracht. Das funktioniert auch soweit ganz gut. Taucht jedoch in den zu serialisierenden Objekte eine List<Foo> auf (wobei es egal ist ob die Liste Elemente enthält oder nicht), dann schlägt die Serialisierung mit folgender Exception+Stacktrace fehl:Beim Generieren des XML-Dokuments ist ein Fehler aufgetreten.
bei System.Xml.Serialization.XmlSerializer.Serialize(XmlWriter xmlWriter, Object o, XmlSerializerNamespaces namespaces, String encodingStyle, String id)
bei System.Xml.Serialization.XmlSerializer.Serialize(XmlWriter xmlWriter, Object o)
bei Kalender.web.RequestFactory.SerializeXMLMessage(Type t, Object _Message)
bei Kalender.web.RequestFactory.CreateKalenderMessage()
bei Kalender.web.Transfer.DoKalenderUpdate()
bei Kalender.sys.ServiceManager.KalenderUpdate() ...Inner Exception:
System.TypeInitializationException
Der Typeninitialisierer für Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterKalenderMessage hat eine Ausnahme verursacht.Inner Exception:
System.NullReferenceException
Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt.
bei Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterKalenderMessage..cctor()Ich habe schon ne Weile rumexperimentiert, und festgestellt das dieses Problem nur auftritt, wenn die Serialisierende Assembly via Reflection geladen wird. Wird sie direkt ausgeführt, dann klappt das Serialisieren.
Zum besseren Verständis hier mal ein wenig Code. Eine Instanz folgender Klasse soll serialisiert werden:
using System; using System.Collections.Generic; using System.Xml.Serialization; namespace Kalender.objects { /// <summary> /// Message zur Übertragung von Kalendereinträgen /// </summary> [Serializable] [XmlType(TypeName = "Message")] public class KalenderMessage { private Header _Header = new Header(); /// <summary> /// Header /// </summary> public Header Header { get { return _Header; } set { _Header = value; } } private List<KalenderEintrag> _KalenderEintraege = new List<KalenderEintrag>(); /// <summary> /// Liste von Kalendereinträgen /// </summary> public List<KalenderEintrag> KalenderEintraege { get { return _KalenderEintraege; } set { _KalenderEintraege = value; } } } }
Die Serialisierung erfolgt so:
private static string SerializeXMLMessage(Type t, object _Message) { MemoryStream ms = new MemoryStream(); XmlSerializer xs = new XmlSerializer(t); XmlTextWriter xw = new XmlTextWriter(ms, _enc); xw.Formatting = Formatting.Indented; xs.Serialize(xw, _Message); ms.Flush(); StreamReader reader = new StreamReader(ms); reader.BaseStream.Seek(0, SeekOrigin.Begin); return reader.ReadToEnd(); }
Soll heißen, oben schiebe ich ein Objekte rein, unten kommt dann ein XML-String raus.
Aufgerufen wird das ganze aus der Hauptanwendung, in dem die .dll mit der Assembly.Load() Methode geladen wird, die entsprechende Klasse instanziert und in dieser eine Methode mit Invoke aufgerufen wird. In dieser Methode wird dann das Objekt erzeugt und Serialisiert.
Was ich schon probiert habe:
- Verändern der Parameter in der zu Serialisierenden Klasse (Konstruktor etc.)
- Hinzufügen aller using-Direktive in der Anwendung die die .dlls lädt
- XML händisch erzeugt --> Deserialisierung schlägt auf die selbe Weise fehl
- alle Möglichkeiten getestet die Assembly mit Reflection zu Laden bzw. die Methoden anders aufzurufen
- Verändern der .Net Framework Version von 2.0 auf 3.5Leider alles ohne Erfolg.
Ich hoffe irgendwer kann mir da Weiterhelfen, bzw. nen Tipp geben wie ich den Fehler da ausmerzen kann, da ich das Laden der Assembly mit Reflection nicht umgehen kann. Evtl. hat ja jemand ne Idee, warum es bei der Serialisierung via Reflection zu solch seltsamen Fehlern kommt.
Grüße, Papa Schmiff
-
Moin,
ohne mich jetzt irgend wann mal ernsthaft mit Serialisierung auseinander gesetzt zu haben ... aber müssen Objekte nicht ein entsprechenden Interface Implementieren um Serialisierung nutzen zu können? ... für List konnte ich im Konstruktor jedenfalls nichts finden http://msdn.microsoft.com/en-us/library/6sh2ey19.aspx
hand, mogel
-
Servus, ne List ist den ich Serialisierbar, solangen Die Items serialisierbar sind. bspw. List<string> müssen serialisierbar sein!!
Wobei.... es geht ja um einen "XML" serialisieren, abgesehen das die Item auch als XML Item serialisierbar sein müssen, könnte es sein das man stat List ein Array verwenden muss... was ich aber nich glaube!!
Wie sieht den der Typ der Items aus ?? Zeig mal code
-
@mogel: Nee nee, es reicht wenn sie das Serilizable Attribut besitzen.
Versuch doch mal Testweise allen Typen in deiner Klasse feste XmlAttribute zu geben.
Hast du auch wirklich keine zusätzlichen Ctors?Weil das würde bedeuten das der Standardctor nicht mehr benutzt wird,XmlSerializer aber einen öffentlichen parameterlosen Ctor benötigt.
Wichtig ist auch, das komplett alles der Klasse public ist, also sowas wie Getter und Setter.
Check das nochmal.
-
@ Firefighter:
XmlAttribute geht für die List<> nicht:
Member 'KalenderEintraege' vom Typ Kalender.objects.KalenderEintrag kann nicht serialisiert werden. XmlAttribute/XmlText kann nicht zum Codieren von komplexen Typen verwendet werden.
bei den primitiven Datentypen geht es ebenfalls nicht. Die scheinen aber auch zu funktionieren.
Konstruktoren habe ich keine weiter. Zugriffsmodifizierer sind auch alle auf public gesetzt jedenfalls interpretier ich folgende als public:
private int _ID; /// <summary> /// ID /// </summary> public int ID { get { return _ID; } set { _ID = value; } }
ich lasse mich da aber gerne vom Gegenteil überzeugen.
@NullBockException:
Prinzipiell sind alle Properties string/int/bool, die ich verwende. Ausschließlich Header sowie KalenderEintrag sind komplexe Typen, wobei diese wiederrum nur aus primitiven bestehen. Der Header lässt sich ohne Probleme serialisieren/deserialisieren. Nur bei der List<> hakts halt.
-
Ok, Problem gelöst:
Die List<> ist nicht das eigentliche Problem, ne List<int> funktioniert ohne weiteres. Es scheint da jedoch Probleme zu geben wenn ne Liste von nem eigenen Typ serialisiert werden soll. Ich hab das jetzt mit nem Array (KalenderEintrag[]) gelöst, die XML Datei ist identisch, Serialisierung/Deserialisierung geht ohne Probleme, auch per Reflection. Danke allen Beteiligten für die Denkanstöße. Mich würde jedoch trotzdem interessieren, warum das mit List<KalenderEintrag> nicht funktioniert, denn so ein Problem wird mich an meinem momentanen Projekt noch öfter erwarten und ne List<> handelt sich doch ein wenig einfacher...
Gruß, PapaSchmiff
-
Wenn du nicht unbedingt an die List<> gebunden bist, schau dir doch mal das hier an http://www.lieser-online.de/blog/?p=25. Der untere Teil könnte für dich interessant sein.