World of Web

Objekt Serialisierung/Deserialisierung

by on Okt.01, 2010, under Datenhaltung

Ziel

Das Ziel in diesem Tutorial ist ein Objekt mithilfe des .NET-Frameworks zu serialisieren bzw. deserialisieren damit es später wiederverwendet werden kann. Das Objekt wird nach der serialisierung als XML Datei gespeichert.

Voraussetzungen

Voraussetzungen für das Tutorial sind zumindest Anfänger bis Fortgeschrittene Kenntnisse in C#. Zum einfacheren Verständnis wird empfohlen das im Tutorial erarbeitete Szenario selbst nach zu programmieren. Hierzu wird das Microsoft Visual Studio empfohlen (ab Version 2005).

Szenario

Für einen kleinen Chat (siehe andere Tutorials) sollen die Benutzer inkl. Passwort und einiger anderer Informationen in einer XML Datei gespeichert werden und durch Objekt serialisierung in einer Objekt-Struktur zurückgegeben werden.

Vorteil dieser Variante:

  • Keine Datenbankanbindung nötig
  • Höchst flexible Anbindung der Daten
  • Daten sind sofort als Objekt-Struktur vorhanden und können auch so benutzt werden
  • Daten sind sehr leicht wieder verwendbar (Stichwort: Interoperabilität)

Ansatz

XML-Struktur

Zunächst einmal sollte die XML-Struktur unseres Objektes festgelegt werden. In diesem Beispiel nutze ich folgende Struktur:

<?xml version="1.0"?>
<UserObject>
   <Users>
      <User>
         <RealName>Maximilian Koepf</RealName>
         <Password>12345</Password>
         <LastLogin>2.12.2008</LastLogin>
      </User>
   </Users>
</UserObject>

UserObject entspricht hier unserem „Root“-Objekt der XML-Struktur. Darauf folgen dann die einzelnen User. Die Informationen die uns über den User gegeben werden sind:

  • Benutzername („name“-Attribut im User-Tag)
  • Realer Name
  • Passwort
  • Letztes Anmeldedatum

Objekt-Struktur

Nun müssen wir beginnen, die XML-Struktur für die Serialisierung als Objekt-Modell nach zu bauen.

Hierfür benötigen wir ein neues Visual-Studio Projekt vom Typ Class Library (Klassen Bibliothek).

Die Objekt-Struktur wird (schematisch) so aussehen:

  • UserObject (root)
    • User
      • UserName
      • RealName
      • Password
      • LastLogin

Wir legen nun als erstes unsere „Root“-Klasse an: das UserObject.

Hierzu erstellen wir eine neue Klasse mit dem Namen UserObject.cs.

UserObject-Klasse

Die UserObjekt Klasse beinhaltet eine Liste aus Benutzern.

(Anmerkung: Es werden erst die Klassen erstellt, die notwendigen Einstellungen zur Serialisierung kommen erst später)

Aufbau der Klasse:

using System;
using System.Collections.Generic;
using System.Text;
 
namespace UserObject
{
   public class UserObject
   {
      private Users users;
 
      public Users Users
      {
         get { return users; }
         set { users = value; }
      }
 
      public UserObject() { }
   }
}

Die „Root“-Klasse UserObject hat als Unter-Objekt eine Variable vom Typ „Users“ die wir gleich noch definieren werden.

Der Konstruktor wird benötigt, falls wir die Objekt-Struktur später auch programmatisch verwenden möchten, was in diesem Szenario sind machen dürfte (es wäre also ein leichtes einen neuen Benutzer anzulegen ohne dabei selbst in der XML-Datei Hand anlegen zu müssen).

Users-Klasse

Die „Users“-Klasse besteht aus einer Liste von Usern.

Aufbau:

using System;
using System.Collections.Generic;
using System.Text;
 
namespace UserObject
{
   public class Users : List<User>
   {
      public Users() { }
   }
}

Die „Users“-Klasse wird also von einer Liste von Usern abgeleitet.

User-Klasse

Nun zur vermutlich interessantesten Klasse: Die „User“-Klasse.

Diese beinhaltet die Attribute der Benutzer.

Aufbau:

using System;
using System.Collections.Generic;
using System.Text;
 
namespace UserObject
{
   public class User
   {
      private string username;
      private string realname;
      private string password;
      private string lastlogin;
 
      public string UserName
      {
         get { return username; }
         set { username = value; }
      }
 
      public string RealName
      {
         get { return realname; }
         set { realname = value; }
      }
 
      public string Password
      {
         get { return password; }
         set { password = value; }
      }
 
      public string LastLogin
      {
         get { return lastlogin; }
         set { lastlogin = value; }
      }
 
      public User() { }
   }
}

Die Serialisierung

Um die Klassen-Struktur nun serialisierbar zu machen, müssen einige Einstellungen vorgenommen werden:

Zunächst mal muss über die Using-Direktive der Namespace System.Xml.Serialization eingebunden werden:

using System.Xml.Serialization;

Danach muss jeder Klasse in der Objekt-Struktur die Eigenschaft „Serializable“ zugewiesen werden:

Dies geschieht indem man

[Serializable]

Über die Klasse schreibt:

using System;
using System.Collections.Generic;
using System.Xml.Serialization;
using System.Text;
 
namespace UserObject
{
   [Serializable]
   public class Users : List<User>
   {
      public Users() { }
   }
}

Nun müssen wir dem Serialisierer nur noch sagen, dass das Property „UserName“ ein Attribut des „User“-Tags ist:

[XmlAttribute("name", DataType = "string")]
public string UserName
{
   get { return username; }
   set { username = value; }
}

Das war auch schon alles.

Nun können wir uns ein kleines Test-Programm schreiben, das eine bestehende XML-Datei deserialisiert, einen Benutzer hinzufügt und diese anschließend wieder speichert.

Das Programm

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Xml.Serialization;
 
namespace UserObject
{
   class TestProgramm
   {
      public static void Main(string[] args)
      {
         string file = "./userdata.xml";
         string outFile = "./userdatanew.xml";
         FileStream xmlFileStream = new FileStream(file, FileMode.Open);
         FileStream xmlOutputStream = new FileStream(outFile, FileMode.OpenOrCreate);
         XmlSerializer xmlSerializer = new XmlSerializer(typeof(UserObject));
         UserObject uObj = (UserObject)xmlSerializer.Deserialize(xmlFileStream);
         User userTwo = new User();
         userTwo.UserName = "Max2";
         userTwo.RealName = "Maximilian Koepf";
         userTwo.Password = "234435345";
         userTwo.LastLogin = "";
         uObj.Users.Add(userTwo);
         xmlSerializer.Serialize(xmlOutputStream, uObj);
         xmlSerializer.Serialize(Console.Out, uObj);
         xmlFileStream.Close();
         xmlOutputStream.Close();
         Console.ReadKey();
      }
   }
}

Die Vorgehensweise des Programms ist relativ simpel:

Es erstellt ein Objekt vom Typ XmlSerializer der auf der Basis unserer „UserObject“-Klasse arbeitet.

Da wir die Properties, etc. genauso genannt haben wie in der XML-Datei müssen wir hier keine weiteren Angaben tätigen. Wir öffnen nun die XML-Datei über einen FileStream, übergeben diesem den Serialisierer und dieser erstellt automatisch das Objekt für uns, auf Basis der XML-Datei.

Danach möchten wir einen neuen Benutzer anlegen (programmatisch) und die XML-Datei danach unter einem neuen Namen speichern.

Der Inhalt der neuen XML-Datei sieht nun so aus:

<?xml version="1.0"?>
<UserObject>  
   <Users>  
      <User>
         <RealName>Maximilian Koepf</RealName>
         <Password>12345</Password>
         <LastLogin>2.12.2008</LastLogin>
      </User>
      <User>
         <RealName>Maximilian Koepf</RealName>
         <Password>234435345</Password>
         <LastLogin />
      </User>
   </Users>
</UserObject>

Man sieht, die Benutzung des Tools ist relativ simpel.

VN:F [1.9.22_1171]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)

Post to Twitter Post to Plurk Post to Yahoo Buzz Post to Delicious Post to Digg Post to Facebook Post to MySpace Post to Ping.fm Post to Reddit Post to StumbleUpon

Share on Facebook




1 Comment for this entry

  • Canary

    Hi, Thanks for these kinds of topical writing as I have been in a position to find here. I agree with most of what’s written the following and I’ll be coming back to this site again.

    VA:F [1.9.22_1171]
    Rating: 0.0/5 (0 votes cast)
    VA:F [1.9.22_1171]
    Rating: 0 (from 0 votes)

Leave a Reply