Mit .Net welche Einschränkungen (falls vorhanden) gibt es bei der Verwendung des XmlSerializer?

8

Verwenden von .Net welche Einschränkungen (falls vorhanden) gibt es bei der Verwendung des XmlSerializer? Können Sie beispielsweise Bilder in XML serialisieren?

    
Gary Willoughby 20.09.2008, 20:45
quelle

8 Antworten

18

Der XmlSerializer hat einige Nachteile.

  1. Es muss alle Typen kennen, die serialisiert werden. Sie können es nicht durch eine Schnittstelle übergeben, die einen Typ darstellt, den der Serializer nicht kennt.
  2. Es kann keine Zirkelverweise geben.
  3. Es wird dasselbe Objekt mehrmals serialisiert, wenn es im Objektdiagramm mehrfach referenziert wird.
  4. Die private Feldserialisierung kann nicht behandelt werden.

Ich habe (dumm) meinen eigenen Serialisierer geschrieben, um einige dieser Probleme zu umgehen. Tu das nicht; Es ist eine Menge Arbeit und Sie werden in den nächsten Monaten kleine Fehler finden. Das Einzige, was ich beim Schreiben meines eigenen Serialisierers und Formatierers gewonnen habe, war eine größere Wertschätzung der Einzelheiten, die bei der Serialisierung von Objektgraphen eine Rolle spielen.

Ich habe den NetDataContractSerializer gefunden, als WCF herauskam. Es macht alles von oben, was XmlSerializer nicht tut. Es steuert die Serialisierung in ähnlicher Weise wie der XmlSerializer. Ein Element enthält verschiedene Eigenschaften oder Felder mit Attributen, die den Serialisierer darüber informieren, was serialisiert werden soll. Ich ersetzte den benutzerdefinierten Serializer, den ich geschrieben hatte, mit dem NetDataContractSerializer und war sehr zufrieden mit den Ergebnissen. Ich kann es nur wärmstens empfehlen.

    
Jason Jackson 20.09.2008, 21:07
quelle
22

Im Allgemeinen finde ich den XmlSerializer zu einer schlechten Wahl für jedes POCO, das mehr als nur ein DTO ist. Wenn Sie eine bestimmte XML-Datei benötigen, können Sie die Xml * Attribute- und / oder IXmlSerializable-Route verwenden - Sie bleiben jedoch mit einem ziemlich verzerrten Objekt zurück.

Für einige Zwecke ist es immer noch eine offensichtliche Wahl - sogar mit seinen Einschränkungen. Aber zum einfachen Speichern und erneuten Laden von Daten habe ich herausgefunden, dass BinaryFormatter eine viel einfachere Wahl mit weniger Fehlern ist.

Hier ist eine Liste einiger Ärgernisse mit XmlSerializer - die meisten, die ich an einem oder anderen Punkt gebissen habe, andere habe ich bei MSDN :

  • Erfordert einen public, no args constructor
  • Serialisiert nur öffentliche Lese- / Schreibeigenschaften und Felder
  • Erfordert, dass alle Typen bekannt sind
  • Ruft tatsächlich get_ * und set_ * auf, damit die Validierung usw. ausgeführt wird. Dies kann gut oder schlecht sein (denken Sie auch an die Reihenfolge der Anrufe)
  • Serialisiert nur IEnumerable- oder ICollection-Sammlungen, die bestimmten Regeln entsprechen
  

Der XmlSerializer behandelt Klassen, die IEnumerable oder ICollection implementieren, speziell. Eine Klasse, die IEnumerable implementiert, muss eine öffentliche Add-Methode implementieren, die einen einzelnen Parameter akzeptiert. Der Parameter der Add-Methode muss vom gleichen Typ sein, wie er von der Current-Eigenschaft für den von GetEnumerator zurückgegebenen Wert oder für eine der Basistypen dieses Typs zurückgegeben wird.

     

Eine Klasse, die ICollection (z. B. CollectionBase) zusätzlich zu IEnumerable implementiert, muss über eine öffentliche Item-indizierte Eigenschaft (Indexer in C #) verfügen, die eine ganze Zahl annimmt und über eine öffentliche Count-Eigenschaft vom Typ integer verfügen muss. Der Parameter für die Add-Methode muss vom gleichen Typ sein, wie er von der Item-Eigenschaft oder einer der Basen dieses Typs zurückgegeben wird. Bei Klassen, die ICollection implementieren, werden Werte, die serialisiert werden sollen, aus der indizierten Item-Eigenschaft abgerufen, nicht durch Aufruf von GetEnumerator.

  • IDictionary
  • wird nicht serialisiert
  • Verwendet dynamisch generierte Assemblys, die möglicherweise nicht aus der App-Domäne entladen werden.
  

Um die Leistung zu erhöhen, generiert die XML-Serialisierungsinfrastruktur dynamisch Assemblys, um bestimmte Typen zu serialisieren und zu deserialisieren. Die Infrastruktur findet und wiederverwendet diese Assemblys. Dieses Verhalten tritt nur bei Verwendung der folgenden Konstruktoren auf:

     

XmlSerializer.XmlSerializer (Typ)   XmlSerializer.XmlSerializer (Typ, String)

     

Wenn Sie einen der anderen Konstruktoren verwenden, werden mehrere Versionen derselben Assembly generiert und nicht entladen, was zu einem Speicherverlust und einer schlechten Leistung führt.

  • ArrayList [] oder List & lt; T & gt; []
  • kann nicht serialisiert werden
  • Hat andere seltsame Randfälle
  

Der XmlSerializer kann nicht instanziiert werden, um eine Enumeration zu serialisieren, wenn die folgenden Bedingungen erfüllt sind: Die Enumeration ist vom Typ unsigned long (ulong in C #) und die Enumeration enthält Elemente mit einem Wert größer als 9,223,372,036,854,775,807.

     

Die XmlSerializer-Klasse serialisiert Objekte, die als [Obsolet] markiert sind, nicht mehr.

     

Sie müssen über die Berechtigung zum Schreiben in das temporäre Verzeichnis (wie in der Umgebungsvariable TEMP definiert) verfügen, um ein Objekt zu deserialisieren.

  • Erfordert das Lesen von .InnerException, um nützliche Informationen zu Fehlern zu erhalten
Mark Brackett 21.09.2008 00:26
quelle
3

Ein weiteres Problem ist, dass das Aufrufen des Konstruktors von XmlSerializer den Code zur Laufzeit kompiliert und eine temporäre DLL (im Ordner% temp%) mit dem Code für die De / Serialisierung generiert.

Sie können den Code sehen, wenn Sie app.config folgende Zeilen hinzufügen:

%Vor%

Dies nimmt viel Zeit in Anspruch, wenn Sie eine Klasse zum ersten Mal serialisieren und Code mit Berechtigungen zum Kompilieren und Schreiben auf die Festplatte benötigen.

Eine Möglichkeit, das zu umgehen, besteht darin, diese DLLs mit dem sGen.exe-Tool, das mit VS 2005+ geliefert wird, vorzukompilieren.

Hier finden Sie weitere Informationen .

    
Tomer Pintel 27.11.2008 11:34
quelle
2

Nicht sicher, ob es irgendwelche Einschränkungen gibt. Aber es gab einen Speicherleck-Fehler in XmlSerialization in .NET 1.1, Sie mussten irgendwie ein Cache-Serializer-Objekt erstellen, um mit diesem Problem umgehen zu können ... Tatsächlich bin ich mir nicht sicher Wenn dieses Problem in .net 2.0 oder neuer behoben wurde ...

    
RWendi 20.09.2008 20:51
quelle
1

Jede Klasse, die Sie schreiben, kann theoretisch über XmlSerializer gespeist werden. Allerdings hat es nur Zugriff auf die öffentlichen Felder, und die Klassen müssen mit den richtigen Attributen (z. B. XmlAttribute) markiert werden. Selbst im grundlegenden Framework unterstützt nicht alles XmlSerializer. System.Collections.Generic.Dictionary & lt; & gt; zum Beispiel.

    
Scott Pedersen 20.09.2008 20:55
quelle
1
___ qstnhdr ___ Mit .Net welche Einschränkungen (falls vorhanden) gibt es bei der Verwendung des XmlSerializer? ___ answer323530 ___

Ein weiteres Problem ist, dass das Aufrufen des Konstruktors von XmlSerializer den Code zur Laufzeit kompiliert und eine temporäre DLL (im Ordner% temp%) mit dem Code für die De / Serialisierung generiert.

Sie können den Code sehen, wenn Sie app.config folgende Zeilen hinzufügen:

%Vor%

Dies nimmt viel Zeit in Anspruch, wenn Sie eine Klasse zum ersten Mal serialisieren und Code mit Berechtigungen zum Kompilieren und Schreiben auf die Festplatte benötigen.

Eine Möglichkeit, das zu umgehen, besteht darin, diese DLLs mit dem sGen.exe-Tool, das mit VS 2005+ geliefert wird, vorzukompilieren.

Hier finden Sie weitere Informationen .

    
___ answer109879 ___

Im Allgemeinen finde ich den XmlSerializer zu einer schlechten Wahl für jedes POCO, das mehr als nur ein DTO ist. Wenn Sie eine bestimmte XML-Datei benötigen, können Sie die Xml * Attribute- und / oder IXmlSerializable-Route verwenden - Sie bleiben jedoch mit einem ziemlich verzerrten Objekt zurück.

Für einige Zwecke ist es immer noch eine offensichtliche Wahl - sogar mit seinen Einschränkungen. Aber zum einfachen Speichern und erneuten Laden von Daten habe ich herausgefunden, dass BinaryFormatter eine viel einfachere Wahl mit weniger Fehlern ist.

Hier ist eine Liste einiger Ärgernisse mit XmlSerializer - die meisten, die ich an einem oder anderen Punkt gebissen habe, andere habe ich bei MSDN :

  • Erfordert einen public, no args constructor
  • Serialisiert nur öffentliche Lese- / Schreibeigenschaften und Felder
  • Erfordert, dass alle Typen bekannt sind
  • Ruft tatsächlich get_ * und set_ * auf, damit die Validierung usw. ausgeführt wird. Dies kann gut oder schlecht sein (denken Sie auch an die Reihenfolge der Anrufe)
  • Serialisiert nur IEnumerable- oder ICollection-Sammlungen, die bestimmten Regeln entsprechen
  

Der XmlSerializer behandelt Klassen, die IEnumerable oder ICollection implementieren, speziell. Eine Klasse, die IEnumerable implementiert, muss eine öffentliche Add-Methode implementieren, die einen einzelnen Parameter akzeptiert. Der Parameter der Add-Methode muss vom gleichen Typ sein, wie er von der Current-Eigenschaft für den von GetEnumerator zurückgegebenen Wert oder für eine der Basistypen dieses Typs zurückgegeben wird.

     

Eine Klasse, die ICollection (z. B. CollectionBase) zusätzlich zu IEnumerable implementiert, muss über eine öffentliche Item-indizierte Eigenschaft (Indexer in C #) verfügen, die eine ganze Zahl annimmt und über eine öffentliche Count-Eigenschaft vom Typ integer verfügen muss. Der Parameter für die Add-Methode muss vom gleichen Typ sein, wie er von der Item-Eigenschaft oder einer der Basen dieses Typs zurückgegeben wird. Bei Klassen, die ICollection implementieren, werden Werte, die serialisiert werden sollen, aus der indizierten Item-Eigenschaft abgerufen, nicht durch Aufruf von GetEnumerator.

  • IDictionary
  • wird nicht serialisiert
  • Verwendet dynamisch generierte Assemblys, die möglicherweise nicht aus der App-Domäne entladen werden.
  

Um die Leistung zu erhöhen, generiert die XML-Serialisierungsinfrastruktur dynamisch Assemblys, um bestimmte Typen zu serialisieren und zu deserialisieren. Die Infrastruktur findet und wiederverwendet diese Assemblys. Dieses Verhalten tritt nur bei Verwendung der folgenden Konstruktoren auf:

     

XmlSerializer.XmlSerializer (Typ)   XmlSerializer.XmlSerializer (Typ, String)

     

Wenn Sie einen der anderen Konstruktoren verwenden, werden mehrere Versionen derselben Assembly generiert und nicht entladen, was zu einem Speicherverlust und einer schlechten Leistung führt.

  • ArrayList [] oder List & lt; T & gt; []
  • kann nicht serialisiert werden
  • Hat andere seltsame Randfälle
  

Der XmlSerializer kann nicht instanziiert werden, um eine Enumeration zu serialisieren, wenn die folgenden Bedingungen erfüllt sind: Die Enumeration ist vom Typ unsigned long (ulong in C #) und die Enumeration enthält Elemente mit einem Wert größer als 9,223,372,036,854,775,807.

     

Die XmlSerializer-Klasse serialisiert Objekte, die als [Obsolet] markiert sind, nicht mehr.

     

Sie müssen über die Berechtigung zum Schreiben in das temporäre Verzeichnis (wie in der Umgebungsvariable TEMP definiert) verfügen, um ein Objekt zu deserialisieren.

  • Erfordert das Lesen von .InnerException, um nützliche Informationen zu Fehlern zu erhalten
___ answer109393 ___

Der XmlSerializer hat einige Nachteile.

  1. Es muss alle Typen kennen, die serialisiert werden. Sie können es nicht durch eine Schnittstelle übergeben, die einen Typ darstellt, den der Serializer nicht kennt.
  2. Es kann keine Zirkelverweise geben.
  3. Es wird dasselbe Objekt mehrmals serialisiert, wenn es im Objektdiagramm mehrfach referenziert wird.
  4. Die private Feldserialisierung kann nicht behandelt werden.

Ich habe (dumm) meinen eigenen Serialisierer geschrieben, um einige dieser Probleme zu umgehen. Tu das nicht; Es ist eine Menge Arbeit und Sie werden in den nächsten Monaten kleine Fehler finden. Das Einzige, was ich beim Schreiben meines eigenen Serialisierers und Formatierers gewonnen habe, war eine größere Wertschätzung der Einzelheiten, die bei der Serialisierung von Objektgraphen eine Rolle spielen.

Ich habe den NetDataContractSerializer gefunden, als WCF herauskam. Es macht alles von oben, was XmlSerializer nicht tut. Es steuert die Serialisierung in ähnlicher Weise wie der XmlSerializer. Ein Element enthält verschiedene Eigenschaften oder Felder mit Attributen, die den Serialisierer darüber informieren, was serialisiert werden soll. Ich ersetzte den benutzerdefinierten Serializer, den ich geschrieben hatte, mit dem NetDataContractSerializer und war sehr zufrieden mit den Ergebnissen. Ich kann es nur wärmstens empfehlen.

    
___ answer109336 ___

Nicht sicher, ob es irgendwelche Einschränkungen gibt. Aber es gab einen Speicherleck-Fehler in XmlSerialization in .NET 1.1, Sie mussten irgendwie ein Cache-Serializer-Objekt erstellen, um mit diesem Problem umgehen zu können ... Tatsächlich bin ich mir nicht sicher Wenn dieses Problem in .net 2.0 oder neuer behoben wurde ...

    
___ qstntxt ___

Verwenden von .Net welche Einschränkungen (falls vorhanden) gibt es bei der Verwendung des XmlSerializer? Können Sie beispielsweise Bilder in XML serialisieren?

    
___ answer109864 ___

Für Auflistungen muss eine Add-Methode ein einzelnes Argument enthalten. Wenn Sie nur ein Textformat und nicht speziell XML benötigen, können Sie JSON ausprobieren. Ich habe einen für .NET, JsonExSerializer entwickelt, und es gibt auch andere, die unter Ссылка .

    
___ tag123xml ___ Die XML-Datei (Extensible Markup Language) ist ein flexibles, strukturiertes Dokumentformat, das Codierungsregeln für Menschen und Maschinen definiert. ___ tag123serialization ___ Serialisierung ist der Prozess, mit dem Datenstrukturen in ein Format konvertiert werden, das leicht gespeichert oder übertragen und anschließend rekonstruiert werden kann. ___ answer109354 ___

Jede Klasse, die Sie schreiben, kann theoretisch über XmlSerializer gespeist werden. Allerdings hat es nur Zugriff auf die öffentlichen Felder, und die Klassen müssen mit den richtigen Attributen (z. B. XmlAttribute) markiert werden. Selbst im grundlegenden Framework unterstützt nicht alles XmlSerializer. System.Collections.Generic.Dictionary & lt; & gt; zum Beispiel.

    
___ tag123net ___ Das .NET-Framework ist ein Software-Framework, das hauptsächlich für das Microsoft Windows-Betriebssystem entwickelt wurde. Es enthält eine Implementierung der Basisklassenbibliothek, Common Language Runtime (allgemein als CLR bezeichnet), Common Type System (allgemein als CTS bezeichnet) und Dynamic Language Runtime. Es unterstützt viele Programmiersprachen, einschließlich C #, VB.NET, F # und C ++ / CLI. NICHT für Fragen zu .NET Core verwenden. ___ antwort109339 ___

Die eine Einschränkung, an die ich denken kann, ist, dass XmlSerialization opt-out ist; was bedeutet, dass alle Eigenschaften einer Klasse, die nicht serialisiert werden soll, mit [XmlIgnore] versehen sein müssen. Im Gegensatz zu DataContractSerializer, bei dem alle Eigenschaften aktiviert sind, müssen Sie die Einschlussattribute explizit deklarieren. Hier ist eine gute Aufzählung .

Bilder oder ihre Binärarrays werden als Base64-kodierter Text von XmlSerializer serialisiert.

    
___ answer109439 ___

Sie können beispielsweise Klassen, die IDictionary-Schnittstelle implementieren, nicht serialisieren.

    
___
Kris 20.09.2008 20:51
quelle
1

Sie können beispielsweise Klassen, die IDictionary-Schnittstelle implementieren, nicht serialisieren.

    
starec 20.09.2008 21:17
quelle
0

Für Auflistungen muss eine Add-Methode ein einzelnes Argument enthalten. Wenn Sie nur ein Textformat und nicht speziell XML benötigen, können Sie JSON ausprobieren. Ich habe einen für .NET, JsonExSerializer entwickelt, und es gibt auch andere, die unter Ссылка .

    
Ted Elliott 21.09.2008 00:17
quelle

Tags und Links