Laden...

Klasse aus Datagrid speichern: XmlSerializer findet keinen Default-Konstruktor

Erstellt von Reaper_97 vor 3 Jahren Letzter Beitrag vor 3 Jahren 969 Views
R
Reaper_97 Themenstarter:in
13 Beiträge seit 2019
vor 3 Jahren
Klasse aus Datagrid speichern: XmlSerializer findet keinen Default-Konstruktor

verwendetes Datenbanksystem: XmlSerializer

Eine Liste der Klasse wird in die datagridview geladen und soll von da aus wieder gespeichert werden falls Änderungen erfolgen. Aber ich bekomme diese Fehler und weiß nicht so weiter.

Fehlermeldung:
"System.InvalidOperationException: "'WindowsFormsApp8.BossFightRewards' kann nicht serialisiert werden, weil dafür kein parameterloser Konstruktor verfügbar ist."

WinForm

public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            List<BossFightRewards> rewards = new List<BossFightRewards>();
            rewards.Add(new BossFightRewards(BossFightRewards.Difficultys.Alpha, BossFightRewards.Trophys.Dragon, 2040));
            dataGridView1.DataSource = rewards;
        }

        private void saveToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        private void loadToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var ofd = new OpenFileDialog();

            if (ofd.ShowDialog() == DialogResult.OK)
            {
                var serializer = new XmlSerializer(typeof(List<BossFightRewards>));
                var reader = new StreamReader(ofd.FileName);
                var input = serializer.Deserialize(reader);
                reader.Close();
                dataGridView1.DataSource = input;
            }
        }

        private void saveToolStripMenuItem2_Click(object sender, EventArgs e)
        {
            var sfd = new SaveFileDialog();
            if (sfd.ShowDialog() == DialogResult.OK)
            {
                var serializer = new XmlSerializer(typeof(List<BossFightRewards>));
                var writer = new StreamWriter(sfd.FileName);

                serializer.Serialize(writer, dataGridView1.DataSource);
                writer.Close();
            }
        }
    }

Extra Klasse.

    class BossFightRewards
    { 
        public int Element { get; set; }
        public Trophys Trophy { get; set; }
        public Difficultys Difficulty { get; set; }

        public enum Difficultys
        {
            Gamma,
            Beta,
            Alpha
        }

        public enum Trophys
        {
            Broodmother,
            Dragon,
            Megapithecus
        }
        public BossFightRewards(Difficultys difficulty, Trophys trophy, int element)
        {
            Difficulty = difficulty;
            Trophy = trophy;
            Element = element;
        }
    }
T
2.219 Beiträge seit 2008
vor 3 Jahren

Das Problem ist, wie die Meldung schon sagt, dass du keinen Default Konstruktor in der Klasse BossFightRewards hat.
Du hast in BossFightRewards einen Konstruktor, der aber nur Parameter entgegen nimmt.
Der Klassenname sollte auch eher BossFightReward heißen.

Intern wird aber beim De-/Serialisieren ein neues Objekt erstellt über den Default Konstruktor und dann befüllt.
Dabei muss es aber einen Konstruktor geben, der keine Parameter entgegen nimmt.
Die entsprechenden Eigenschaften werden dann erst beim ein-/auslesen verwendet.
Wenn du einen Konstruktor anlegst, der Parameter annimmt, dann wird von .NET kein Default Konstruktor mehr beim builden erstellt.
Nur wenn es keinen Konstruktor in der Klasse gibt, wird auch von .NET selbst einer angelegt.


// Default Konstruktor ohne Funktion
public BossFightRewards()
{
}

Lies sich dort am besten nochmal ein!

Nachtrag:
Wenn du viele Einträge in deiner Liste hast, würde ich dir empfehlen von XML zu einer SQLite Datenbank zu wechseln.
XML hat einen großen Overhead, was viel CPU/RAM frisst beim De-/Serialisieren.
Alternativ kannst du dir auch mit Newtonsoft.Json auch eine json Datei anlegen, diese ist dann auch kleiner ein einfacher zu parsen.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

R
Reaper_97 Themenstarter:in
13 Beiträge seit 2019
vor 3 Jahren

Danke für die Antwort. Habe noch nicht viel mit Xml gemacht und wusste jz nicht genau was gemeint war. Hab es mal so abgeändert und funktioniert wieder.

public class BossFightReward
    { 
        public int Element { get; set; }
        public Trophys Trophy { get; set; }
        public Difficultys Difficulty { get; set; }

        public enum Difficultys
        {
            Gamma,
            Beta,
            Alpha
        }

        public enum Trophys
        {
            Broodmother,
            Dragon,
            Megapithecus
        }
        public BossFightReward(Difficultys difficulty, Trophys trophy, int element)
        {
            Difficulty = difficulty;
            Trophy = trophy;
            Element = element;
        }
        public BossFightReward()
        {
        }
    }
T
2.219 Beiträge seit 2008
vor 3 Jahren

Hat weniger mit XML direkt zu tun als mit dem Serializier von .NET.
Solltest dich ggf. einlesen dazu, da du auch an deren Stellen über das Problem stolpern wirst.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.