C# Schulaufgabe (Persistenz von Daten)

Griffindor01

Cadet 3rd Year
Registriert
Feb. 2021
Beiträge
33
Ich mal wieder,

haben nun bei uns im Bezug auf den Unterricht neues Material bekommen, habe einiges alleine hinbekommen, verzweifle aber nun an einem Arbeitsblatt mit dem Titel "Persistenz von Daten", also per Definiton der dauerhaften Speicherung von Daten bzw. Objekten auf einem nichtflüchtigen Speicher-Medium.

In der PDF wurden die Klassen "StreamReader" und "StreamWriter" sowie "XMLSerializer" vorgestellt.

Im Vorhinein habe ich bereits, den Aufgabe nach, ein Adressbuch erstellt mit Personen-Objekten, welche diverse Daten wie Namen, Nachnamen, Adresse (Eigene Klasse) und die Postleitzahl enthalten.


Aufgabe ist nun:

Ergänzen Sie ihr Adressbuch-Projekt so, dass nach dem Programmstart die Prozessdaten gelesen
und bei Programmende geschrieben werden.
Modularisieren Sie diese Funktionalität in geeigneten Methoden der Klasse Program, die Sie
dann bei Bedarf aufrufen (siehe Beispiel-Code).

C#:
namespace [B][I]Adressbuch[/I][/B]
{
class Program
{
static void Main(string[] args)
{
// Lesen der Prozessdaten (Programmstart)
List<Person> personen = (List<Person>)readData();
// Alles Mögliche machen…
// Schreiben der Prozessdaten (Programmende)
writeData(personen);
}
static void writeData(List<Person> personen)
{
XmlSerializer serializer = new XmlSerializer(typeof(List<Person>));
using (StreamWriter writer = new StreamWriter("Adressbuch.xml"))
{
serializer.Serialize(writer, personen);
}
}
static object readData()
{
object o;
XmlSerializer serializer = new XmlSerializer(typeof(List<Person>));
using (StreamReader reader = new StreamReader("Adressbuch.xml"))
{
o = serializer.Deserialize(reader);
}
return o;
}
}
}



Soweit ich das verstanden habe, muss ich also zunächst einmal meine Liste mit den Personen-Objekten Serialisieren lassen, also in einer XML-Datei speichern, diese dann einlesen, bei Bedarf verändern und schließlich ausgeben lassen.


Nun mein Problem: Habe genau wie in der PDF beschrieben versucht, den Listen-Container des Typs Person zu Serialisieren, das Programm wird sogar ausgeführt, eine XML-Datei wird erstellt, diese enthält aber keine Angaben über die Objekte sondern ist bis auf die Platzhalter leer:
C#:
<?xml version="1.0" encoding="utf-8"?>
<ArrayOfPerson xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Person />
  <Person />
  <Person />
  <Person />
  <Person />
</ArrayOfPerson>

Aussehen soll das ganze aber beispielhaft so:
C#:
<?xml version="1.0" encoding="utf-8"?>
<ArrayOfPerson xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Person>
<Vorname>Uwe</Vorname>
<Nachname>Homm</Nachname>
<Geburtstag>2020-12-24T00:00:00</Geburtstag>
<Adressen>
<Adresse>
<Strasse>Sudetenstrasse</Strasse>
<Hausnr>5a</Hausnr>
<Plz>64521</Plz>
<Ort>Groß-Gerau</Ort>
</Adresse>
</Adressen>
</Person>
<Person>
<Vorname>Friedhelm</Vorname>
<Nachname>Ernst</Nachname>
<Geburtstag>2020-12-31T00:00:00</Geburtstag>
<Adressen>
<Adresse>
<Strasse>Darmstädter Straße</Strasse>
<Hausnr>90</Hausnr>
<Plz>65421</Plz>
<Ort>Groß-Gerau</Ort>
</Adresse>
<Adresse>
<Strasse>Uhugasse</Strasse>
<Hausnr>7</Hausnr>
<Plz>60489</Plz>
<Ort>Frankfurt</Ort>
</Adresse>
</Adressen>
</Person>
</ArrayOfPerson>




Meine Main sieht folgendermaßen aus (Falls ich auch die anderen Klassen senden soll, sagt bitte bescheid:

[/CODE]

class Program
{
static void Main(string[] args)

{







Person Mustermann = new Person();
Person Dieter = new Person("Dieter", "Bohlen", new DateTime(2004, 05, 02), new Adresse("Bohlenweg", "1", "50667", "Köln"));
Person Thomas = new Person("Thomas", "Mustermann", new DateTime(2003, 02, 01), new Adresse("Mehringdamm", "4", "30021", "Berlin"));
Person Franz = new Person("Franz", "Gans", new DateTime(2005, 07, 03), new Adresse("Rosenhof", "5", "64560", "Riedstadt"));
Person Tommy = new Person("Tommy", "Test", new DateTime(1958, 03, 01), new Adresse("Kirchweg", "5", "77765", "Hochstadt"));
personen.Add(Mustermann);
personen.Add(Dieter);
personen.Add(Thomas);
personen.Add(Franz);
personen.Add(Tommy);
Adresse computerbase = new Adresse("Putinweg", "2", "74627", "Internet");
Dieter.addNeueAdresse(computerbase );


XmlSerializer serializer = new XmlSerializer(typeof(List<Person>));
using (StreamWriter writer = new StreamWriter("Adressbuch.xml");
{

serializer.Serialize(writer, personen);
}




foreach (Person person in personen)

{
Console.WriteLine(
person.getVorname() + "\n" +
person.getNachname() + "\n" +
person.getGeburtstag().ToShortDateString() + "\n");
List<Adresse> adressen = person.getAdresseListe();


foreach (Adresse adresse in adressen)

{
Console.WriteLine(adresse.getStrasse());
Console.WriteLine(adresse.getHausnr());
Console.WriteLine(adresse.getPlz());
Console.WriteLine(adresse.getOrt());
Console.WriteLine("");

}

Console.WriteLine("===============");



[/CODE]



Relevant ist hierbei aber eigentlich nur der Serialisierungs-Bereich.


Wäre nett, wenn mir jemand helfen kann
 
Zuletzt bearbeitet:
In deiner class Person steht bestimmt

private string vorname;
private string nachname;

usw.

Anstatt private muss dort public stehen. Dann kann der XmlSerializer auch drauf zugreifen und die XML Datei so bauen wie du sie haben willst.
 
Danke

Nochmal eine Frage, beim genaueren hinsehen habe ich bemerkt, dass von meinen Personen-Objekten nur ein Teil dort hineingeschrieben wird und nicht die Adresse, die auch Teil des Personen-Objektes ist (eben nur in Form in einer eigenen Klasse).

In der PDF heißt es hierzu:
Und nun noch das Bonbon :-) Jedes Person-Objekt enthält wiederum einen Container mit
Adresse-Objekten. Da ja alle Felder eines Objekts serialisiert werden, werden nun auch noch
alle Adresse-Objekte serialisiert

Dies trifft bei mir aber wie gesagt nicht zu ...


Meine Klassen:


Person:
C#:
using System;
using System.Collections.Generic;
using System.Linq;

namespace KlasseMasse
{
    public class Person
    {

        List<Adresse> adressen = new List<Adresse>();
        List<Person> personen = new List<Person>();



        // Eigenschaften
        public string vorname;
        public string nachname;
        public DateTime geburtstag;
     
    

        // Konstruktoren

        public Person()
        {
            vorname = "Erika";
            nachname = "Mustermann";
            geburtstag = new DateTime(1964, 8, 12);
            addNeueAdresse(new Adresse());

        }

        public Person(string _vor, string _nach, DateTime _geb, Adresse _adr)
        {
            vorname = _vor;
            nachname = _nach;
            geburtstag = _geb;
            addNeueAdresse(_adr);

        }

        // Get und Set Methoden
        public void setStraße(string _vor)
        {
            vorname = _vor;
        }
     
        public string getVorname()
        {
            return vorname;
        }

        public void setNachname(string _nach)
        {
            nachname = _nach;
        }

        public string getNachname()
        {
            return nachname;
        }

        public void setGeburtstag(DateTime _geb)
        {
            geburtstag = _geb;
        }

        public DateTime getGeburtstag()
        {
            return geburtstag;
        }

        public void addNeueAdresse(Adresse _adr)
        {
         
         
            adressen.Add(_adr);
         
         


        }

        public List<Adresse> getAdresseListe()
        {

            return adressen;
         
         

        }

       [\code]
    
    
     





    }
}


Adresse:
C#:
using System;
using System.Collections.Generic;
using System.Text;

namespace KlasseMasse
{
    public class Adresse // Klassen-Name
    {
        // Eigenschaften (Attribute).
        public string strasse;
        public string hausnr;
        public string plz;
        public string ort;

        // Konstruktoren
        public Adresse() // Den Attributen der Klasse werden Namen bereitgestellt, sofern bei Instanziierung keine Werte angegeben.
        {
            strasse = "Heidestraße";
            hausnr = "17";
            plz = "51147";
            ort = "Köln";
        }

        public Adresse(string _str, string _hnr, string _plz, string _ort) // Werte werden Parametern zugewiesen, sofern definiert. Strasse = Erster Wert, der als _str definiert wurde.
        {
            strasse = _str;
            hausnr = _hnr;
            plz = _plz;
            ort = _ort;
        }

        // Set und Get Methoden
        public void setStrasse(string _str) // Der string _str, also gleichgesetzter string Straße wird an Methode überreicht.
        {
            strasse = _str;
        }
       
        public string getStrasse() // Straße wird ausgegeben
        {

            return strasse;
        }

        public void setHausnr(string _hnr) // Der string _hnr, also gleichgesetzter string Hausnummer wird an Methode überreicht.
        {
            hausnr = _hnr;
        }

        public string getHausnr() // Hausnummer wird ausgegeben
        {
            return hausnr;
        }

        public void setPlz(string _plz) // Der string _plz, also gleichgesetzter string Postleitzahl wird an Methode überreicht.
        {
            plz = _plz;
        }

        public string getPlz() // Postleitzahl wird ausgegeben
        {
            return plz;
        }
       
        public void setOrt(string _ort) // Der string _ort, also gleichgesetzter string Ort wird an Methode überreicht. Attribut kriegt Wert Parameter
        {
            ort = _ort;
        }

        public string getOrt() // Ort wird ausgegeben
        {
            return ort;
        }

       


    }
}
[\code]


Die Main:

C#:
List<Person> personen = new List<Person>();
            


            



            Person Mustermann = new Person();
            Person Dieter = new Person("Dieter", "Bohlen", new DateTime(2004, 05, 02), new Adresse("Bohlenweg", "1", "50667", "Köln"));
            Person Thomas = new Person("Thomas", "Mustermann", new DateTime(2003, 02, 01), new Adresse("Mehringdamm", "4", "30021", "Berlin"));
            Person Franz = new Person("Franz", "Gans", new DateTime(2005, 07, 03), new Adresse("Rosenhof", "5", "64560", "Riedstadt"));
            Person Tommy = new Person("Tommy", "Test", new DateTime(1958, 03, 01), new Adresse("Kirchweg", "5", "77765", "Hochstadt"));
            personen.Add(Mustermann);
            personen.Add(Dieter);
            personen.Add(Thomas);
            personen.Add(Franz);
            personen.Add(Tommy);
            Adresse zweiteadresse = new Adresse("Putinweg", "2", "74627", "Test");
            Dieter.addNeueAdresse(zweiteadresse);


            




            foreach (Person person in personen)

            {
                Console.WriteLine(
                person.getVorname() + "\n" +
                person.getNachname() + "\n" +
                person.getGeburtstag().ToShortDateString() + "\n");
                List<Adresse> adressen = person.getAdresseListe();
                

                foreach (Adresse adresse in adressen)

                {
                    Console.WriteLine(adresse.getStrasse());
                    Console.WriteLine(adresse.getHausnr());
                    Console.WriteLine(adresse.getPlz());
                    Console.WriteLine(adresse.getOrt());
                    Console.WriteLine("");

                }

                Console.WriteLine("===============");

                



            }
            
            XmlSerializer serializer = new XmlSerializer(typeof(List<Person>));
            using (StreamWriter writer = new StreamWriter("Adressliste.xml"))
            {
                
                {
                    serializer.Serialize(writer, personen);

                }



              
                
            }

[\code]
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: Superior1337
Superior1337 schrieb:
In deiner class Person steht bestimmt

private string vorname;
private string nachname;

usw.

Anstatt private muss dort public stehen. Dann kann der XmlSerializer auch drauf zugreifen und die XML Datei so bauen wie du sie haben willst.
Bitte nochmal über meinen Beitrag obendrüber schauen, hab vergessen dich zu markieren
 
Auf einen schnellen Blick würde ich sagen dasselbe Problem:

In class Person:

List<Adresse> adressen = new List<Adresse>();

ein public davor:

public List<Adresse> adressen = new List<Adresse>();

Versuchs mal.
 
Superior1337 schrieb:
Auf einen schnellen Blick würde ich sagen dasselbe Problem:

In class Person:

List<Adresse> adressen = new List<Adresse>();

ein public davor:

public List<Adresse> adressen = new List<Adresse>();

Versuchs mal.

Genau da lag der Fehler, du bist Klasse! Danke vielmals
 
  • Gefällt mir
Reaktionen: Superior1337
Den XmlSerializer kenn ich nicht so genau, aber ich denke es gibt auch Attribute mit denen man private Fields und Properties serialisieren kann.
 
Auch mal mit Attributen auseinandersetzen. Ich seh zB nirgendwo
C#:
[Serializable]
.

Wenn nicht schon passiert ist auch ein Blick auf Access Modifier in C# sinnvoll, ggfs einschließlich sealed, für ein grundsätzliches Verständnis dafür, was für Auswirkungen diese haben.

Public ist oft die schlechtestmögliche Idee.
 
  • Gefällt mir
Reaktionen: Ice-Lord und KitKat::new()
Zurück
Oben