Freigeben über


Einführung in die XML-Serialisierung

Serialisierung beschreibt den Vorgang des Konvertierens eines Objekts in eine Form, die problemlos transportiert werden kann. So können Sie beispielsweise ein Objekt serialisieren und es über das Internet per HTTP zwischen einem Client und einem Server transportieren. Am anderen Ende wird das Objekt durch Deserialisierung aus dem Stream rekonstruiert.

Bei XML-Serialisierung werden nur die öffentlichen Felder und Eigenschaftenwerte eines Objekts in einen XML-Stream serialisiert. Typinformationen werden bei der XML-Serialisierung nicht berücksichtigt. Wenn Sie z. B. über ein Book-Objekt im Library-Namespace verfügen, wird es nicht in jedem Fall in ein Objekt desselben Typs deserialisiert.

Hinweis   Bei der XML-Serialisierung werden Methoden, Indexer, private Felder und Nur-Lesen-Eigenschaften nicht konvertiert (außer bei schreibgeschützten Auflistungen). Verwenden Sie statt der XML-Serialisierung BinaryFormatter, wenn alle öffentlichen und privaten Felder und Eigenschaften eines Objekts serialisiert werden sollen.

Die zentrale Klasse bei der XML-Serialisierung ist die XmlSerializer-Klasse, und die wichtigsten Methoden sind die Serialize-Methode und die Deserialize-Methode. Der mit Hilfe der XmlSerializer-Klasse erzeugte XML-Stream entspricht der XSD-Empfehlung (XML Schema Definition Language) 1.0 des World Wide Web Consortium (www.w3.org). Darüber hinaus sind die generierten Datentypen mit dem Dokument "XML Schema Part 2: Datatypes" (nur auf Englisch verfügbar) kompatibel.

Die Daten in den Objekten werden durch Konstrukte der Programmiersprache beschrieben, z. B. Klassen, Felder, Eigenschaften, primitive Typen, Arrays oder auch eingebettetes XML in Form eines XmlElement-Objekts oder XmlAttribute-Objekts. Sie können eigene, mit Attributen versehene Klassen erstellen oder mit Hilfe des XML Schema Definition-Tools Klassen anhand eines vorhandenen XML-Schemas generieren.

Wenn Sie über ein XML-Schema verfügen, können Sie das XML Schema Definition-Tool ausführen und so eine Reihe von Klassen erstellen, die eine strikte Typbindung an dieses Schema haben und mit Attributen versehen sind. Wird eine Instanz einer solchen Klasse serialisiert, entspricht der erzeugte XML-Stream dem XML-Schema. Wenn Sie über eine solche Klasse verfügen, können Sie mit einem leicht zu ändernden Objektmodell programmieren und sich dabei sicher sein, dass der erzeugte XML-Stream dem XML-Schema entspricht. Diese Vorgehensweise stellt eine Alternative zur Verwendung anderer Klassen in .NET Framework dar, z. B. der XmlReader-Klasse und der XmlWriter-Klasse, um einen XML-Stream auszuwerten und zu schreiben. (Weitere Informationen zur Verwendung dieser Klassen finden Sie unter Verwenden von XML in .NET Framework.) Diese Klassen ermöglichen Ihnen das Auswerten von beliebigen XML-Streams. Dagegen wird die XmlSerializer-Klasse verwendet, wenn davon ausgegangen wird, dass der XML-Stream einem bekannten XML-Schema entspricht.

Der von der XmlSerializer-Klasse generierte XML-Stream wird durch Attribute gesteuert, wodurch das Festlegen von XML-Namespace, Elementname, Attributname usw. des XML-Streams ermöglicht wird. Weitere Informationen zu diesen Attributen und zum Steuern der XML-Serialisierung mit diesen Attributen finden Sie unter Steuern der XML-Serialisierung mit Attributen. Eine Tabelle dieser Attribute, die zum Steuern des generierten XML-Streams verwendet werden, finden Sie unter Attribute für die Steuerung der XML-Serialisierung.

Die XmlSerializer-Klasse ermöglicht eine weiter gehende Serialisierung von Objekten und kann einen XML-Stream von codiertem SOAP generieren. Der erzeugte XML-Stream entspricht dem im Abschnitt 5 des vom World Wide Web Consortium herausgegebenen Dokuments mit dem Titel "Simple Object Access Protocol (SOAP) 1.1" (nur auf Englisch verfügbar). Weitere Informationen zu diesem Prozess finden Sie unter Generieren von SOAP-Meldungen mit der XML-Serialisierung. Eine Tabelle der Attribute, die den generierten XML-Stream steuern, finden Sie unter Attribute für die Steuerung der Serialisierung von codiertem SOAP.

Die XmlSerializer-Klasse generiert die SOAP-Meldungen, die von den XML-Webdiensten erstellt und an diese übergeben werden. Um die SOAP-Meldungen zu steuern, können Sie Attribute auf die Klassen, Rückgabewerte, Parameter und Felder anwenden, die in einer XML-Webdienstdatei (ASMX-Datei) gefunden wurden. Sie können sowohl die unter "Attribute für die Steuerung der XML-Serialisierung" als auch die unter "Attribute für die Steuerung der Serialisierung von codiertem SOAP" aufgeführten Attribute verwenden, da ein XML-Webdienst entweder literales oder codiertes SOAP verwenden kann. Weitere Informationen zum Verwenden von Attributen zum Steuern des durch einen XML-Webdienst generierten XML-Streams finden Sie unter XML-Serialisierung mit XML-Webdiensten. Weitere Informationen zu SOAP und XML-Webdiensten finden Sie unter Anpassen von SOAP-Meldungen.

Sichern von XmlSerializer-Anwendungen

Bei der Erstellung einer Anwendung, die den XmlSerializer verwendet, sollten Ihnen die folgenden Elemente und deren Bedeutung bekannt sein:

  • Der XmlSerializer erzeugt C#-Dateien (CS-Dateien) und kompiliert sie in dem von der Umgebungsvariablen TEMP benannten Verzeichnis in DLL-Dateien. Die Serialisierung findet mit diesen DLLs statt.

    Der Code und die DLLs sind während der Erstellung und der Kompilierung nicht vor bösartigen Prozessen geschützt. Auf einem Computer unter Microsoft Windows NT 4.0 oder höher können zwei oder mehr Benutzer das Verzeichnis temp gleichzeitig verwenden. Dies birgt allerdings Risiken, wenn erstens die Benutzerkonten verschiedene Sicherheitsberechtigungen haben und zweitens unter dem Konto mit der höheren Sicherheitsberechtigung eine Anwendung mit XmlSerializer ausgeführt wird. Ist das der Fall, kann ein Benutzer die Sicherheit des Computers beeinträchtigen, indem er entweder die CS- oder die DLL-Datei ersetzt, die gerade kompiliert wird. Stellen Sie zur Vermeidung dieser Gefahr sicher, dass jedes Konto auf dem Computer ein eigenes Profil hat. So verweist die Umgebungsvariable TEMP in der Standardeinstellung für jedes Konto auf verschiedene Verzeichnisse.

  • Wenn ein bösartiger Benutzer einen ständigen Stream von XML-Daten an einen Webserver sendet (Denial-of-Service-Angriff), verarbeitet der XmlSerializer die Daten, bis dem Computer keine Ressourcen mehr zur Verfügung stehen.

    Diese Art von Angriff kann vereitelt werden, indem ein Computer mit Internet-Informationsdienste (Internet Information Services, IIS) verwendet wird und die Anwendung innerhalb von IIS ausgeführt wird. IIS verfügt über ein Gate, das Datenströme, die eine festgelegte Größe überschreiten (der Standardwert ist 4 KB), nicht verarbeitet. Bei der Erstellung einer Anwendung, die IIS nicht verwendet und die Deserialisierung mit XmlSerializer ausführt, empfiehlt es sich, ein entsprechendes Gate zu implementieren, das Denial-of-Service-Angriffe verhindert.

  • Der XmlSerializer serialisiert Daten und führt Code von einem beliebigen übergebenen Typ aus.

    Ein bösartiges Objekt stellt in zweierlei Hinsicht eine Gefahr dar. Es kann bösartigen Code ausführen oder bösartigen Code in die mit XmlSerializer erzeugte C#-Datei einfügen. Im ersten Fall verhindert die Codezugriffssicherheit Schäden, wenn ein bösartiges Objekt versucht, einen zerstörerischen Prozess auszuführen. Im zweiten Fall besteht theoretisch die Möglichkeit, dass es einem bösartigen Objekt gelingt, Code in die mit XmlSerializer erzeugte C#-Datei einzufügen. Obwohl das Problem genau untersucht wurde und ein solcher Angriff als unwahrscheinlich gilt, empfiehlt es sich, keine Daten eines unbekannten oder nicht vertrauenswürdigen Typs zu serialisieren.

  • Serialisierte vertrauliche Daten sind möglicherweise gefährdet.

    Nach der Serialisierung von Daten durch XmlSerializer können diese als XML-Datei oder in einem anderen Datenspeicher gespeichert werden. Wenn der Datenspeicher auch anderen Prozessen zugänglich oder in einem Intranet bzw dem Internet sichtbar ist, können die Daten gestohlen und in bösartiger Absicht verwendet werden. Die Daten einer Anwendung, die z. B. Aufträge mit Kreditkartennummern serialisiert, sind besonders heikel. Achten Sie deshalb immer auf den Schutz des Datenspeichers, und führen Sie die entsprechenden Maßnahmen durch, um Verborgenheit zu gewährleisten.

Serialisierung einer einfachen Klasse

Im folgenden Beispiel wird eine einfache Klasse mit einem öffentlichen Feld dargestellt.

Public Class OrderForm
    Public OrderDate As DateTime
End Class
[C#]
public class OrderForm{
    public DateTime OrderDate;
}

Wird eine Instanz dieser Klasse serialisiert, ist sie möglicherweise vergleichbar mit folgendem Beispiel.

<OrderForm>
    <OrderDate>12/12/01</OrderDate>
</OrderForm>

Weitere Beispiele zur Serialisierung finden Sie unter Beispiele für die XML-Serialisierung.

Serialisierbare Elemente

Folgende Elemente können mit Hilfe der XmLSerializer-Klasse serialisiert werden.

  • Öffentliche Lese-/Schreibeigenschaften und Felder von öffentlichen Klassen.
  • Klassen, die ICollection oder IEnumerable implementieren. (Beachten Sie, dass nur Auflistungen serialisiert werden, keine öffentlichen Eigenschaften.)
  • XmlElement-Objekte.
  • XmlNode-Objekte.
  • DataSet-Objekte.

Serialisieren und Deserialisieren von Objekten

Wenn Sie ein Objekt serialisieren möchten, erstellen Sie zuerst das zu serialisierende Objekt, und legen Sie dann dessen öffentliche Eigenschaften und Felder fest. Dazu müssen Sie das Transportformat angeben, in dem der XML-Stream gespeichert werden soll – als ein Stream oder als eine Datei. Wenn der XML-Stream beispielsweise in einer permanenten Form gespeichert werden muss, erstellen Sie ein FileStream-Objekt. Beim Deserialisieren eines Objekts wird durch das Transportformat festgelegt, ob Sie ein Stream- oder ein Dateiobjekt erstellen. Nachdem Sie das Transportformat bestimmt haben, können Sie je nach Bedarf entweder die Serialize-Methode oder die Deserialize-Methode aufrufen.

So serialisieren Sie ein Objekt

  1. Erstellen Sie das Objekt, und legen Sie seine öffentlichen Felder und Eigenschaften fest.

  2. Konstruieren Sie mit Hilfe des Objekttyps eine XmlSerializer-Klasse. Weitere Informationen erhalten Sie unter den XmlSerializer-Klassenkonstruktoren.

  3. Rufen Sie die Serialize-Methode auf, um einen XML-Stream oder eine Darstellung in Dateiform der öffentlichen Eigenschaften und Felder des Objekts zu generieren. Im folgenden Beispiel wird eine Datei erstellt.

    Dim myObject As MySerializableClass = New MySerializableClass()
    ' Insert code to set properties and fields of the object.
    Dim mySerializer As XmlSerializer = New XmlSerializer(GetType(MySerializableClass))
    ' To write to a file, create a StreamWriter object.
    Dim myWriter As StreamWriter = New StreamWriter("myFileName.xml")
    mySerializer.Serialize(myWriter, myObject)
    
    [C#]
    MySerializableClass myObject = new MySerializableClass();
    // Insert code to set properties and fields of the object.
    XmlSerializer mySerializer = new 
    XmlSerializer(typeof(MySerializableClass));
    // To write to a file, create a StreamWriter object.
    StreamWriter myWriter = new StreamWriter("myFileName.xml");
    mySerializer.Serialize(myWriter, myObject);
    

So deserialisieren Sie ein Objekt

  1. Konstruieren Sie zur Deserialisierung mit Hilfe des Objekttyps eine XmlSerializer-Klasse.

  2. Rufen Sie die Deserialize-Methode auf, um ein Replikat des Objekts zu erstellen. Bei der Deserialisierung müssen Sie das zurückgegebene Objekt wieder in den Originaltyp umwandeln, wie in folgendem Beispiel gezeigt. Im folgenden Beispiel wird das Objekt in eine Datei deserialisiert, es könnte aber genauso gut in einen Stream deserialisiert werden.

    Dim myObject As MySerializableClass
    ' Constructs an instance of the XmlSerializer with the type
    ' of object that is being deserialized.
    Dim mySerializer As XmlSerializer = New XmlSerializer(GetType(MySerializableClass))
    ' To read the file, creates a FileStream.
    Dim myFileStream As FileStream = _
    New FileStream("myFileName.xml", FileMode.Open)
    ' Calls the Deserialize method and casts to the object type.
    myObject = CType( _
    mySerializer.Deserialize(myFileStream), MySerializableClass)
    [C#]
    MySerializableClass myObject;
    // Constructs an instance of the XmlSerializer with the type
    // of object that is being deserialized.
    XmlSerializer mySerializer = 
    new XmlSerializer(typeof(MySerializableClass));
    // To read the file, creates a FileStream.
    FileStream myFileStream = 
    new FileStream("myFileName.xml", FileMode.Open);
    // Calls the Deserialize method and casts to the object type.
    myObject = (MySerializableClass) 
    mySerializer.Deserialize(myFileStream)
    

Weitere Beispiele zur XML-Serialisierung finden Sie unter Beispiele für die XML-Serialisierung.

Vorteile der XML-Serialisierung

Über die XmlSerializer-Klasse können Sie die Serialisierung eines Objekts in einen XML-Stream vollständig und auf flexible Weise steuern. Beim Erstellen eines XML-Webdienstes können Sie Attribute zur Steuerung der Serialisierung auf Klassen und Member anwenden, um zu gewährleisten, dass die XML-Ausgabe einem bestimmten Schema entspricht.

So haben Sie mit der XmlSerializer-Klasse folgende Möglichkeiten:

  • Angeben, ob ein Feld oder eine Eigenschaft als Attribut oder als Element codiert werden soll.
  • Angeben des zu verwendenden XML-Namespace.
  • Angeben eines Elementnamens oder Attributnamens, wenn ein Feld- oder Eigenschaftsname ungeeignet ist.

Ein weiterer Vorteil bei der XML-Serialisierung besteht darin, dass es für die Anwendung, die Sie entwickeln, keine Einschränkungen gibt, so lange der generierte XML-Stream mit einem bestimmten Schema übereinstimmt. Nehmen wir z. B. ein Schema zur Beschreibung von Büchern, das die Elemente Titel, Autor, Verlag und ISBN enthält. Sie können eine Anwendung entwickeln, die die XML-Daten auf gewünschte Weise verarbeitet, so z. B. als Buchbestellung oder Bücherbestand. In beiden Fällen besteht die einzige Anforderung darin, dass der XML-Stream mit dem festgelegten XSD-Schema (XML Schema Definition Language) übereinstimmt.

Überlegungen zur XML-Serialisierung

Folgende Punkte sollten bei der Verwendung der XmLSerializer-Klasse berücksichtigt werden.

  • Die serialisierten Daten bestehen nur aus den Daten selbst und der Klassenstruktur. Typidentität und Assemblyinformationen sind nicht enthalten.
  • Es können nur öffentliche Eigenschaften und Felder serialisiert werden. Verwenden Sie statt der XML-Serialisierung die BinaryFormatter-Klasse, wenn Sie nicht öffentliche Daten serialisieren müssen.
  • Eine Klasse muss einen Standardkonstruktur besitzen, damit sie über die XmlSerializer-Klasse serialisiert werden kann.
  • Methoden können nicht serialisiert werden.
  • XmlSerializer kann Klassen verarbeiten, die IEnumerable oder ICollection unterschiedlich implementieren, abhängig davon, ob sie bestimmte Anforderungen erfüllen. Eine Klasse, die IEnumerable implementiert, muss eine öffentliche Add-Methode mit einem einzigen Parameter implementieren. Der Parameter der Add-Methode muss mit dem Typ konsistent (polymorph) sein, der von der IEnumerator.Current-Eigenschaft zurückgegeben wurde, die wiederum von der GetEnumerator-Methode zurückgegeben wurde. Eine Klasse, die ICollection zusätzlich zu IEnumerable implementiert (z. B. CollectionBase), muss eine öffentliche und mit Item indizierte (Indexer in C#) Eigenschaft mit einer ganzen Zahl sowie eine öffentliche Count-Eigenschaft vom Typ Integer aufweisen. Der an die Add-Methode übergebene Parameter muss von demselben Typ sein, den die Item-Eigenschaft zurückgibt, oder muss ein Basistyp dieses Typs sein. Bei Klassen, die ICollection implementieren, werden die zu serialisierenden Werte nicht durch einen Aufruf von GetEnumerator, sondern über die indizierte Item-Eigenschaft abgerufen. Bedenken Sie außerdem, dass öffentliche Felder und Eigenschaften nicht serialisiert werden, mit Ausnahme von öffentlichen Feldern, die eine andere Auflistungsklasse zurückgeben (die ICollection implementiert). Ein Beispiel finden Sie unter Beispiele für die XML-Serialisierung.

XSD-Datentypzuordnungen

Das vom World Wide Web Consortium (www.w3.org) herausgegebene Dokument mit dem Titel "XML Schema Part 2: Datatypes" (nur auf Englisch verfügbar) führt die einfachen Datentypen auf, die in einem XSD-Schema (XML Schema Definition Language) zulässig sind. Für viele dieser Typen (z. B. int und decimal) ist ein entsprechender Datentyp in .NET Framework vorhanden. Dies ist aber nicht bei allen XML-Datentypen der Fall, so gibt es z. B. für den Datentyp NMTOKEN in .NET Framework keine Entsprechung. Wenn Sie dann mit Hilfe des XML Schema Definition-Tools (Xsd.exe) Klassen aus einem Schema generieren, wird ein entsprechendes Attribut auf den Member einer Typzeichenfolge angewendet, und seine DataType-Eigenschaft wird auf den Namen des XML-Datentyps festgelegt. Enthält ein Schema beispielsweise ein Element namens MyToken mit dem XML-Datentyp NMTOKEN, dann könnte die generierte Klasse wie in folgendem Beispiel gezeigt einen Member enthalten.

<XmlElement(DataType:="NMTOKEN")>
Public MyToken As String
[C#]
[XmlElement(DataType = "NMTOKEN")]
public string MyToken;

Ebenso sollten Sie beim Erstellen einer Klasse, die einem bestimmten XSD-Schema (XML) entspricht, die entsprechenden Attribute anwenden und die DataType-Eigenschaft auf den gewünschten Namen für den XML-Datentyp festlegen.

Eine vollständige Liste mit Datentypzuordnungen finden Sie unter der jeweiligen DataType-Eigenschaft einer der folgenden Attributklassen: SoapAttributeAttribute, SoapElementAttribute, XmlArrayItemAttribute, XmlAttributeAttribute, XmlElementAttribute oder XmlRootAttribute.

Siehe auch

XML- und SOAP-Serialisierung | XMLSerializer.Serialize | BinaryFormatter | Binäre Serialisierung | Serialisieren von Objekten | XmlSerializer | FileStream | Beispiele für die XML-Serialisierung