Serialisierung und Deserialisierung Daten flexibel l speichern

Ähnliche Dokumente
Programmieren lernen in ASP.NET mit C#

XML Schema und Objektorientierung

WPF Steuerelemente. Dr. Beatrice Amrhein

Komponenten & Frameworks Seite 1

Gobales Gedächtnis. AntMe. Sebastian Loers. lb-sys.info. Projekt: AntMe - Globales Gedächtnis (Version 1.0)

1)Login Funktion ohne Datenbank

Statische und Nichtstatische Methoden Properties/ Eigenschaften

Objektorientierung. Marc Satkowski 20. November C# Kurs

Unsere Webapplikation erweitern

Prüfung Softwareentwicklung II (IB)

Vererbung I. Kfz Eigenschaften und Methoden der Klasse Kfz Lkw. Pkw. Eigenschaften und Methoden der Klasse Kfz

Ereignisse (Events) Asynchrones Versenden von Informationen Sender (Herausgeber) Empfänger (Abonnent) Dr. Beatrice Amrhein

C# - Einführung in die Programmiersprache Arrays, Enumeration und Collections. Leibniz Universität IT Services Anja Aue

Städtisches Gymnasium Olpe Java Ht Informatik - Q1 Die Klasse List im Abitur Methoden und Beispielcode Hier alle wichtigen Methoden. Ein Beispielcode

hue12 January 24, 2017

Programmierung für Mathematik (HS13)

Praktische Einführung in.net. Kai Stammerjohann

Lösungshinweise/-vorschläge zum Übungsblatt 11: Software-Entwicklung 1 (WS 2017/18)

AuD-Tafelübung T-B5b

FH D. Objektorientierte Programmierung in Java FH D FH D. Prof. Dr. Ing. André Stuhlsatz. Referenzen. Referenzen

Benutzerhandbuch WSCAD Datenpunktliste Konvertierung nach Datenpunktliste VDI 3814

Objektserialisierung / Memento-Pattern

Einstieg in die Informatik mit Java

TERRA PosBackup Service Verfahrensdokumentation

Ich liebe Java && Ich liebe C# Rolf Borst

Probeklausur: Programmierung WS04/05

Prof. W. Henrich Seite 1

Attributed Prototyped Class Factories

Dynamische Webseiten mit PHP. Oder: LAMP - The open way

Anleitung zur Benutzung des Admin Control Panel

WPF Bindung. Dr. Beatrice Amrhein

Kapitel 8: Serialisierbarkeit

Die Warenkorbfunktion (workbasket)

Klausur Software-Entwicklung März 01

Wuerfel - augenzahl: int + Wuerfel() + wuerfeln() + gibaugenzahl(): int

Klausur Grundlagen der Programmierung

Verkettete Datenstrukturen: Listen

Informatik B. Vorlesung 14 Serialisierung, Autoboxing. Dr. Ralf Kunze

Application Frameworks and Componentware Wintersemester 2002/03. Komponentenbasierte Programmierung in Java

Institut für Programmierung und Reaktive Systeme 2. Februar Programmieren I. Übungsklausur

II.4.1 Unterklassen und Vererbung - 1 -

II.4.5 Generische Datentypen - 1 -

Grundlagen der Informatik

II.4.1 Unterklassen und Vererbung - 1 -

XSD - XML Schema Definition

Allgemeine Hinweise:

Objektserialisierung

Shoutcast Listing. Version Dezember 2016

Play Framework, MySQL, JPA, HQL, HTML, jquery,

Problemstellung. Object1:Klasse1. Object2:Klasse2 att1: Klasse1 att2: 9. att1: att2: 17. Klasse1 att1 att2 Klasse2 att1 att2

Institut für Programmierung und Reaktive Systeme 6. Juli Programmieren II. Übungsklausur

Eclipse Tutorial.doc

Programmieren für Wirtschaftswissenschaftler SS 2015

Delegates. «Delegierter» Methoden Schablone Funktionszeiger. Dr. Beatrice Amrhein

Web-basierte Anwendungssysteme PHP Teil 2

C# - Einführung in die Programmiersprache Methoden. Leibniz Universität IT Services

Einführung in die Programmierung

Unified-E Standard WebHttp Adapter

PK-Einstufungstest. 1. Allgemeine Multiple-Choice-Aufgaben

! 1. Rekursive Algorithmen.! 2. Rekursive (dynamische) Datenstrukturen. II.3.2 Rekursive Datenstrukturen - 1 -

Deklaration einer Klasse Innere innerhalb Klassen einer in Ja anderen v a Klasse

Heap vs. Stack vs. statisch. 6 Speicherorganisation. Beispiel Statische Variablen. Statische Variablen

Implementieren von Klassen

Informatik - Übungsstunde

JavaScript. Dies ist normales HTML. Hallo Welt! Dies ist JavaScript. Wieder normales HTML.

Grundlagen der Informatik / Algorithmen und Datenstrukturen. Aufgabe 139

JAVA BASICS. 2. Primitive Datentypen. 1. Warum Java? a) Boolean (logische Werte wahr & falsch)

Die Syntax von Java. Ursprünge. Konsequenzen. Das Wichtigste in Kürze. Weiteres Vorgehen. Rund um Java. Sun Microsystems. Borland Software Corp

Grundlagen der Informatik 2

Heap vs. Stack vs. statisch. 6 Speicherorganisation. Beispiel Statische Variablen. Statische Variablen

Kapitel 9 Schnittstellen

1. Rekursive Algorithmen 2. Rekursive (dynamische) Datenstrukturen

Internet-Technologien

Rechtsbelehrung. Java und OOP Das Buch Christian Silberbauer 144

Erzeugungsmuster. Kapselung der Objekt-Erzeugung

Grundlagen Internet-Technologien INF3171

Schleifen Datenfelder (Arrays) Verzweigungen

Schlussendlich geben wir die Listen aus. Es kommt zu folgender Ausgabe:

Tipps und Hinweise zum Bezug der Beitragssatzdatei V5.0

II.4.1 Unterklassen und Vererbung - 1 -

Probeklausur Datenbanken und Informationssysteme II

WPF Steuerelemente Listbox, ComboBox, ListView,

<form name= test action= test.php method= get autocomplete= on > </form> <form name= test action= test.php method= post autocomplete= on > </form>

Tutorial 7 TEIL 2/2. Untersuchung von ebusiness Anwendungen auf der Basis des IBM WebSphere Developer V 7.0

Teil 2: Weitere Aspekte der Objektorientierung

7. Verkettete Strukturen: Listen

Schwerpunkte. Verkettete Listen. Verkettete Listen: 7. Verkettete Strukturen: Listen. Überblick und Grundprinzip. Vergleich: Arrays verkettete Listen

Angewandte Softwareentwicklung Serialisierung

PK-Einstufungstest. 1. Allgemeine Multiple-Choice-Aufgaben. Aufgabe 1.1. Alle Aufgaben beziehen sich auf Java.

6 Speicherorganisation

ITG RKSVNet - Webservice Signierung von Belegen via Internet

Übung 1 mit C# 6.0 MATTHIAS RONCORONI

Avamboo GmbH Avamboo Encrypt. SICHERE MIT Avamboo Encrypt. für Outlook 2010 / 2013 / Handbuch

Transkript:

Serialisierung und Deserialisierung Daten flexibel l speichern Autor: Thomas Bandt Datum: 1. November 2007 Inhalt Ausgangslage und Lösung...2 Die Datenbank...2 Das Formular...2 Einsammeln der Daten...3 Serialisieren und Speichern der Daten...4 Deserialisieren und Abrufen der Profildaten...6 Formular automatisch vorbelegen...7 Zusammenfassung...8 2007 69 - Vervielfältigung, online wie offline, nur nach ausdrücklicher schriftlicher Genehmigung.

Seite 2 Ausgangslage und Lösung Es gibt Situationen in der Praxis eines (Web-) Entwicklers, in denen er Daten flexibel speichern und präsentieren möchte. Bei mir war der Anlass für die Entwicklung der nachfolgend beschrieben Vorgehensweise ein Protokoll, welches vom Benutzer einer Webanwendung ausgefüllt werden muss. Das Protokoll besteht selbst aus etwa 30 Fragen, welche wiederum unterschiedlichste Antwortmöglichkeiten zulassen. Kann man einmal einen Text oder eine Zahl eingeben (TextBox), ist bei anderen Fragen die Antwort via Multiple- oder Singlechoice (CheckBoxList vs. RadioButtonList oder DropDownList) möglich. Das impliziert nun drei Probleme, die es zu lösen gilt: 1. Wie hält man das Formular so flexibel, dass man bei Änderungen, die vorauszusehen sind, nicht einen riesigen Rattenschwanz an Nacharbeiten generiert? 2. Wie bildet man das als Objekt vernünftig ab? 3. Wie speichere ich das vernünftig in der Datenbank? Mögliche Lösungen mag es einige geben, mal mehr, mal weniger kompliziert. Ich verzichte an dieser Stelle auf eine Gegenüberstellung und konzentriere mich auf den Weg, für den ich mich entschieden habe: das automatisierte Binden und Speichern der Formulardaten in eine Liste, die Serialisierung dieser Liste und die anschließende Speicherung des generierten XML in einem einzigen Datenbankfeld. Die Datenbank Die Datenbank kann aussehen wie sie will. Zum Speichern des kompletten Formulars wird nur ein einziges Feld benötigt - das kann ein Blob, ein normales Textfeld oder das neue XML-Feld im SQL Server 2005 sein. Für mein Beispiel war mir das alles zu aufwendig ich speichere das Profil einfach in einer XML-Datei auf dem Filesystem :-). Das Formular Das Formular ist ein ganz normales ASP.NET-Formular bestehend aus den normalen WebControls. Um uns die Sache einfacher zu machen wird es eingegrenzt durch ein Panel warum und wieso, dazu gleich mehr. Später kann das Formular ohne auch nur eine einzige Zeile Code anfassen zu müssen beliebig erweitert, geändert oder sogar verkleinert werden. <asp:panel ID= ProfileDataPanel runat= server > Mein Name <asp:textbox ID= Name runat= server /> Mein Land <asp:dropdownlist ID= Country runat= server > <asp:listitem></asp:listitem> <asp:listitem Value= 1 >Deutschland</asp:ListItem> <asp:listitem Value= 2 >Österreich</asp:ListItem> <asp:listitem Value= 3 >Schweiz</asp:ListItem> </asp:dropdownlist>

Seite 3 Meine Lieblingsautos <asp:checkboxlist ID= MyCars runat= server > <asp:listitem Value= 1 >Ferrari</asp:ListItem> <asp:listitem Value= 2 >Trabant</asp:ListItem> <asp:listitem Value= 3 >Porsche</asp:ListItem> </asp:checkboxlist> <asp:button ID= Button1 runat= server Text= Profil speichern onclick= Button1_Click /> </asp:panel> Einsammeln der Daten Hier wird es jetzt interessant. Ich hatte gerade erwähnt, dass man beim Ändern des Formulars später keine Zeile Code schreiben muss, und dass das Formular in einem Panel eingebettet ist, hier nun der Grund: ProfileAttributeCollection profile = new ProfileAttributeCollection(); foreach (Control c in ProfileDataPanel.Controls) if (c!= null) switch (c.gettype().name) case "DropDownList": DropDownList ddl = c as DropDownList; if (!string.isnullorempty(ddl.selectedvalue)) profile.add(new ProfileAttribute(c.ID, ddl.selectedvalue)); case "TextBox": TextBox tb = c as TextBox; if (!string.isnullorempty(tb.text)) profile.add(new ProfileAttribute(c.ID, tb.text)); case "CheckBoxList": CheckBoxList cbl = c as CheckBoxList; foreach (ListItem li in cbl.items) if (li.selected) profile.add(new ProfileAttribute(c.ID, li.value)); BL.Profile.SaveProfile(profile); Zuerst wird ein neues Profil-Objekt erstellt, in dem die einzelnen Profileigenschaften gespeichert werden. Eine Profileigenschaft ist letztlich nichts weiter als eine Klasse mit einer Property für den Schlüssel, der Beschreibt um welche Eigenschaft es sich handelt, und einer Property für den Wert:

Seite 4 public class ProfileAttribute public ProfileAttribute() public ProfileAttribute(string key, string value) this.key = key; this.value = value; private string key; private string value; public string Key get return key; set key = value; public string Value get return value; set this.value = value; Diese Eigenschaften werden gesammelt in der ProfileAttributeCollection: public class ProfileAttributeCollection : List<ProfileAttribute> Das sind die zwei zentralen Geschäftsobjekte, mit denen ich hier arbeite die können natürlich beliebig erweitert und angepasst werden. Nun zum spannenderen Teil. spätere Eingriffe in den Code werden dadurch vermieden, dass beim Speichern des Profils alle Controls innerhalb des eingrenzenden Panels automatisch abgerufen und ausgewertet werden. Dabei wird schlicht geprüft um welchen Typ es sich handelt, ist es ein Control welches relevante Daten beinhaltet, wird dies ausgewertet: bei einer TextBox wird schlicht die Text-Eigenschaft herangezogen, bei einer CheckBoxList, die ja mehrere Antwort-Möglichkeiten bietet, wird für jede getroffene Antwort ein entsprechender Eintrag in der Profil-Collection angelegt. Das lässt sich natürlich noch erweitern, z.b. um andere Controls oder um eine Rekursion, falls das Formular aufwendiger gestaltet und verschachtelt ist. Serialisieren und Speichern der Daten Haben wir nun alle Daten in der Collection zusammen, wird diese im Business Layer verarbeitet, d.h. serialisiert. Serialisierung heißt in diesem Fall die Erzeugung eines XML-Markups, welches alle Informationen dieses Objektes letztendlich als Text enthält, die notwendig sind, um das Objekt nachher auch wieder zurück zu wandeln denn darin liegt ja der Zauber.

Seite 5 public static void SaveProfile(ProfileAttributeCollection profile) if (profile!= null && profile.count > 0) // Serialize XmlSerializer s = new XmlSerializer(typeof(ProfileAttributeCollection)); StringWriter p = new StringWriter(new StringBuilder()); s.serialize(p, profile); // Save DA.Profile.UpdateProfile(p.GetStringBuilder().ToString()); else DA.Profile.UpdateProfile(null); Das generierte XML kann übrigens so aussehen: <?xml version="1.0" encoding="utf-16"?> <ArrayOfProfileAttribute xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xmlns:xsd="http://www.w3.org/2001/xmlschema"> <ProfileAttribute> <Key>Name</Key> <Value>Thomas</Value> </ProfileAttribute> <ProfileAttribute> <Key>Country</Key> <Value>3</Value> </ProfileAttribute> <ProfileAttribute> <Key>MyCars</Key> <Value>2</Value> </ProfileAttribute> <ProfileAttribute> <Key>MyCars</Key> <Value>3</Value> </ProfileAttribute> </ArrayOfProfileAttribute> Enthalten ist hier der Name, die Auswahl des Landes sowie zwei ausgewählte Autos aus der Auto-Liste MyCars. Wurde aus dem Objekt ein einfacher String erzeugt, der das XML-File enthält, wird dieser String nun gespeichert wie oben schon erwähnt, geschieht das in meinem Fall der Einfachheit halber einfach durch das Speichern in einer XML-Datei. public static void UpdateProfile(string profile) string filename = HttpContext.Current.Server.MapPath("~/App_Data/profile.xml"); using(textwriter tw = new StreamWriter(filename)) tw.writeline(profile);

Seite 6 Deserialisieren und u Abrufen der Profildaten Fangen wir unten an, beim Auslesen des XML-Strings aus der XML-Datei: public static string GetProfile() string filename = HttpContext.Current.Server.MapPath("~/App_Data/profile.xml"); using (TextReader tr = new StreamReader(filename)) return tr.readtoend(); Und gehen gleich weiter zum Deserialisieren: public static ProfileAttributeCollection GetProfile() string source = DA.Profile.GetProfile(); if(!string.isnullorempty(source) && source.trim().length > 0) XmlSerializer s = new XmlSerializer(typeof(ProfileAttributeCollection)); TextReader profile = new StringReader(source); return s.deserialize(profile) as ProfileAttributeCollection; return null; Hier wird nun also aus dem gespeicherten XML wieder ein echtes Objekt gemacht, welches danach sofort weiterverwendet werden kann, um etwa das Formular wieder vorzubelegen.

Seite 7 Formular automatisch vorbelegen Das tun wir dann auch mal wir binden also die gesammelten Profildaten an die einzelnen Formularelemente. protected void Page_Load(object sender, EventArgs e) // Databinding if (!Page.IsPostBack) ProfileAttributeCollection profile = BL.Profile.GetProfile(); if (profile!= null && profile.count > 0) foreach (ProfileAttribute a in profile) foreach (Control c in ProfileDataPanel.Controls) if (c!= null && a.key == c.id) switch (c.gettype().name) case "DropDownList": DropDownList ddl = c as DropDownList; foreach (ListItem li in ddl.items) if (li.value == a.value) li.selected = true; case "TextBox": TextBox tb = c as TextBox; tb.text = a.value; case "CheckBoxList": CheckBoxList cbl = c as CheckBoxList; foreach (ListItem li in cbl.items) if (li.value == a.value) li.selected = true; Das sieht auf den ersten Blick vielleicht etwas aufwendiger aus als das Einsammeln, letztlich ist es aber der gleiche Prozess nur in umgekehrter Reihenfolge.

Seite 8 Für jede der in der Collection befindlichen Profil-Eigenschaften wird nun in einer Schleife geschaut, ob ein passendes Formularelement zur Verfügung steht. Das funktioniert, weil die ID der Formularelemente der der Profileigenschaften entspricht. Wurde nun beispielsweise eine Eigenschaft gestrichen oder durch eine andere ersetzt, muss man den Code nicht anpassen dann passiert hier schlicht nichts. Sinnvollerweise kann man ihn aber so erweitern, dass man veraltete Einträge dann automatisch löscht. Zusammenfassung Das gezeigte und im Anhang als Download verfügbare Beispiel soll nur einen Überblick über die Möglichkeiten bieten, man kann es natürlich noch verfeinern und ausbauen. Der grundlegende Vorgang hat sich bei mir aber als praxistauglich erwiesen. Das Protokoll ist seit mehreren Monaten im Einsatz und wird erfolgreich und fleißig ausgefüllt :-).