Laden...

XML Serialisierung und Interfaces

Erstellt von peter.goessweiner vor 15 Jahren Letzter Beitrag vor 15 Jahren 7.937 Views
P
peter.goessweiner Themenstarter:in
56 Beiträge seit 2007
vor 15 Jahren
XML Serialisierung und Interfaces

Hallo!

Ich habe eine Klasse, welche von einem Interface abgeleietet ist. Diese Klasse beinhaltet wiederum eine Liste von Objekten, welche auch von einem Interface abgeleitet sind.

Wenn ich nun diese Klasse per XML serialisieren möchte, erhalte ich folgende Fehlermeldung:

[System.InvalidOperationException] = {"Fehler beim Reflektieren des Typs 'Benutzerverwaltung.Gruppe'."}
InnerException = {"Das Member 'Benutzerverwaltung.Gruppe.userList' des Typs 'System.Collections.Generic.IList`1[[BusinessLayer.Interfaces.IBenutzer, BusinessLayer, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]' kann nicht serialisiert werden. Details finden S...

Hier mal meine bisherige Implementierung:

Interface IBenutzer

    public interface IBenutzer
    {
        IList<IGruppe> groupList { get; set; }
    }

Interface IGruppe

    public interface IGruppe
    {
        IList<IBenutzer> userList { get; set; }
    }

Klasse:


namespace Benutzerverwaltung
{
    [Serializable]
    public class Gruppe : IGruppe
    {
        public IList<IBenutzer> userList { get; set; }

        internal Gruppe()
        {
                   userList = new List<IBenutzer>();
        }

    }

    [Serializable]
    public class Benutzer : IBenutzer
    {
        public IList<IGruppe> groupList { get; set; }

        internal Benutzer()
        {
                  groupList = new List<IGruppe>();
        }

    }
}

wenn ich nun den Befehl

XmlSerializer mySerializer = new XmlSerializer(typeof(Gruppe));

aufrufe, erhalte ich eine Exception.

Kann mir jemand einen Tipp geben, was ich vergessen habe?

Danke,

lg Peter

1.200 Beiträge seit 2007
vor 15 Jahren

Der Serializer weiss halt nicht, welche Liste er serialisieren soll, weil du nur ein Interface als Member angegeben hast, würde ich mal denken.

Ersetz doch einfach mal IList<T> durch z.B. List<T>

Shift to the left, shift to the right!
Pop up, push down, byte, byte, byte!

YARRRRRR!

3.971 Beiträge seit 2006
vor 15 Jahren

Interfaces und abstrakte Klassen lassen sich nicht serialisieren.

Vor dem Serialisieren eines Objektstammes müsstest du den Stamm und seine entsprechenden Unterklassen in Klassentypen wandeln. Diese Kopie lässt sich anschließend serialisieren.

Eine andere Möglichkeit wäre, in deinem Stamm-Objekt implementierst du IXmlSerializable und übernimmst eigenhändig das serialisieren.

Es gibt 3 Arten von Menschen, die die bis 3 zählen können und die, die es nicht können...

P
peter.goessweiner Themenstarter:in
56 Beiträge seit 2007
vor 15 Jahren

Danke für die schnellen Antworten!

Ich habe jetzt meine Unterklassen in Klassentypen umgewandelt, allerdings bekomme ich jetzt bei der XML Serialisierung eine Exception: Es wurde ein zirkulärer Verweis gefunden.

Ist natürlich klar, da Gruppe eine Benutzerliste und Benutzer die Gruppenliste speichert. Kann ich dem XMLSerializer irgendwie sagen, dass er nur die erste Ebene (Rekursionstiefe 1) der Liste nimmt.?

also

<Gruppe>
   <Benutzer>
   <Benutzer>
</Gruppe>

und nicht

<Gruppe>
  <Benutzer>
     <Gruppe>
         <Benutzer>
             <Gruppe>
                ...

oder bin ich da gezwungen, IXmlSerializable zu implementieren um alles selber zu machen?

5.742 Beiträge seit 2007
vor 15 Jahren

oder bin ich da gezwungen, IXmlSerializable zu implementieren um alles selber zu machen?

Ja.
Die einzige Möglichkeit die dir, abgesehen davon, noch bleibt, ist das Attribut XmlIgnore auf die Gruppe Property von Benutzer anzuwenden - eventuell schränkt das in deinem Fall aber zu sehr ein.

P
peter.goessweiner Themenstarter:in
56 Beiträge seit 2007
vor 15 Jahren

ok danke für die Info.

ich habe mich für [XmlIgnore] entschieden, weil ich in meiner Gruppe eine...

void AddUser(Benutzer newUser)
{
   this.userList.Add(newUser);
   newUser.groupList.Add(this);
}

... Methode habe.

Somit kann ich ich beim deserialisieren auch auf die Gruppen eines Benutzers zugreifen.

IXmlSerializable werde ich implementieren, wenn ich mehr Zeit habe! 🙂

O
778 Beiträge seit 2007
vor 15 Jahren

Was du im Übrigen auch machen kannst, ist statt dem XmlSerializer (dem übrigens das Serializable-Attribut egal sein sollte) den System.Runtime.Serialization.Formatters.Soap.SoapFormatter (so oder so ähnlich, hat in jedem Fall eine eigene Assembly) benutzen, der erzeugt auch Xml und kommt glaube ich sogar mit zirkulären Verweisen zurecht, ABER du kannst das Aussehen der Xml-Datei in keinster Weise beeinflussen...

3.971 Beiträge seit 2006
vor 15 Jahren

Bitte bei der Verwendung von XmlSoap beachten, dass dort einige Sachen anders laufen (private Felder werden beispielsweise deserialisiert) und das XmlSoap für den Datenaustausch gedacht ist. Xml ist (meistens) leichter zu editieren als XmlSoap

Es gibt 3 Arten von Menschen, die die bis 3 zählen können und die, die es nicht können...