Laden...

Kann XML nicht mehr deserialisieren - Eigene Klassen in Verwendung

Erstellt von mipa_acc vor 13 Jahren Letzter Beitrag vor 13 Jahren 1.033 Views
M
mipa_acc Themenstarter:in
318 Beiträge seit 2006
vor 13 Jahren
Kann XML nicht mehr deserialisieren - Eigene Klassen in Verwendung

Hallo,

ich habe ein Problem. Ich habe eine Klasse (WordUserList) ich ich serialisiert habe. Wenn ich die XML nun wieder deserialisieren will, bekomme ich eine OutOfRange Exception. Ich bin völlig ratlos warum dies so ist.

So sehen meine Klassen aus:


  //Hier müssen alle Typen angegeben werden, mit denen ich in der WordUserList arbeite.
    //Das Problem ist, dass der Serialisierungsvorgang on the fly passiert. Deswegen muss ich vorher schon angeben,
    //mit welchen selbstgeschriebenen Klassen ich arbeite, dass der XMLSerializer das Schema meiner Klassen kennt.
    [Serializable]
    [XmlInclude(typeof(WordUser))]
    [XmlInclude(typeof(Department))]
    public class WordUserList :IEnumerable, IEnumerator {

        [XmlIgnore]
        private int _Position = -1;

        private List<WordUser> _Content;

        #region Properties
        
        public List<WordUser> Content {
            get { return _Content; }
            set { _Content = value; }
        }
        #endregion

        /* Needed since Implementing IEnumerable*/        
        public IEnumerator GetEnumerator() {

            return (IEnumerator)this;
        
        }

        /* Needed since Implementing IEnumerator*/        
        public bool MoveNext() {

            if (_Position < _Content.Count - 1) {

                _Position++;
                return true;
            } else {

                return false;
            
            }
        
        }

        /* Needed since Implementing IEnumerator*/        
        public void Reset() {

            _Position = -1;
        
        }

        /* Needed since Implementing IEnumerator*/        
        public object Current {
            get {
                return _Content[_Position];
            }
        }
                
        public WordUserList() {

            _Content = new List<WordUser>();

        }
                
        public void Add(WordUser user) {

            _Content.Add(user);
        
        }
                
        public void Add(object user) {

            

        }
                
        public void SaveList() {

            SaveTheList(@"S:\Allgemein\Word_2007_Makros\ExOffTab.xml");
        
        }
                
        public void SaveList(string path) {

            SaveTheList(path);

        }
                
        private void SaveTheList(string path) {

            try {

                XMLHelper.SaveInXml(this, path);

            } catch {

                System.Windows.Forms.MessageBox.Show("Fehler beim speichern der ExOffTab.xml", "ExOffTab.Core", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error);
            
            }
            
        
        }



    [Serializable]
    [XmlInclude(typeof(Department))]
    public class WordUser {

        private string _Name;
        private List<Department> _AllowedDepartments;
        private string _LastUsedTemplate;
        private string _LastUsedName;
        private string _LastUsedPrinter;


        public string UserName {
            get { return _Name; }
            set { _Name = value; }
        }

        public List<Department> AllowedDepartments {
            get { return _AllowedDepartments; }
            set { _AllowedDepartments = value; }
        }

        public string LastUsedTemplate {
            get { return _LastUsedTemplate; }
            set { _LastUsedTemplate = value; }
        }

        public string LastUsedName {
            get { return _LastUsedName; }
            set { _LastUsedName = value; }
        }

        public string LastUsedPrinter {
            get { return _LastUsedPrinter; }
            set { _LastUsedPrinter = value; }
        }

        public WordUser() { 
        
        
        }

    }


    [Serializable]
    public enum Department {

        Fertigteile,
        Garagen,
        Holzbau,
        Bausanierung,
        Verwaltung,
        Komplettbau,
        IngBuero,
        Leipzig,
        CSV,
        Dahmit

    }


 public class XMLHelper {

        public static WordUserList LoadFromXml(string pathToFile) {

            WordUserList tempBase = new WordUserList();

            XmlSerializer xmlSer = new XmlSerializer(typeof(WordUserList));
            FileStream myStream = new FileStream(pathToFile, FileMode.Open);
            tempBase = (WordUserList)xmlSer.Deserialize(myStream);

            myStream.Close();

            return tempBase;
        }


        public static void SaveInXml(WordUserList wordUserList, string savepath) {

            XmlSerializer xmlSer = new XmlSerializer(typeof(WordUserList));
            FileStream myStream = new FileStream(savepath, FileMode.Create);
            xmlSer.Serialize(myStream, wordUserList);

            myStream.Close();

        }


    }

Ich bekomme nicht direkt einen Fehler, sondern Sobald die XML Datei wieder deserialisiert wird ( tempBase = (WordUserList)xmlSer.Deserialize(myStream); ) steht in meinem tempBase Objekt bei der Propertie Current diese System.ArgumentOutOfRange Exception.

Könnt Ihr mir bitte etwas auf die Sprünge helfen... Kapier´s leider grad gar nicht.

Vielen Dank im Voraus!

Gruß

2.891 Beiträge seit 2004
vor 13 Jahren

Ich bekomme nicht direkt einen Fehler, sondern Sobald die XML Datei wieder deserialisiert wird [...] steht in meinem tempBase Objekt bei der Propertie Current diese System.ArgumentOutOfRange Exception.

Wie du ja sicherlich weißt, serialisiert der XML-Serializer alle öffentlichen Properties (Betonung auf "öffentlich" und auf "Properties").

Daher wird dann der Getter von "Current" fehlschlagen, weil "_Content" nicht wieder deserialisiert wurde.

Gruß,
dN!3L

M
mipa_acc Themenstarter:in
318 Beiträge seit 2006
vor 13 Jahren

Verdammt... hab den Wald vor lauter Bäumen nicht gesehen.

Vielen Dank!

Irgendwie hab ich aber trotzdem noch das Problem, dass der XMLSerializer trotz dem [XmlIgnore] Attribut des Current Propertie versucht zu deserialisieren... Hab ich da noch was übersehen?


        #region Properties
        public List<WordUser> Content {
            get { return _Content; }
            set { _Content = value; }
        }

        /* Needed since Implementing IEnumerator*/
        [XmlIgnore]
        public object Current {
            get {
                return _Content[_Position];
            }
        }
        #endregion

Gruß

49.485 Beiträge seit 2005
vor 13 Jahren

Hallo dN!3L

Daher wird dann der Getter von "Current" fehlschlagen, weil "_Content" nicht wieder deserialisiert wurde.

_Content selbst wird nicht serialisiert, aber Content sollte serialisiert werden. Und Content macht nichts anders als _Content zu setzen bzw. zu lesen.

Hallo mipa_acc,

Irgendwie hab ich aber trotzdem noch das Problem, dass der XMLSerializer trotz dem [XmlIgnore] Attribut des Current Propertie versucht zu deserialisieren... Hab ich da noch was übersehen?

er versucht nicht die Current Property zu serialisieren, sondern die Content-Property. Current würde er schon deshalb nicht serialisieren, weil die keinen Setter hat. Ein [XmlIgnore] vor Current ändert also nichts und ist überflüssig.

herbivore

2.891 Beiträge seit 2004
vor 13 Jahren

_Content selbst wird nicht serialisiert, aber Content sollte serialisiert werden. Und Content macht nichts anders als _Content zu setzen bzw. zu lesen.

Oh, stimmt. Da hast du recht.

Aber "_Position" wird nicht mit serialisiert. D.h. nach der Deserialisierung hat es seinen Standardwert "-1". Wenn du dann in "Current" auf _Content[_Position] zurgreift, bekommst du eine ArgumentOutOfRangeException.

Gruß,
dN!3L

M
mipa_acc Themenstarter:in
318 Beiträge seit 2006
vor 13 Jahren

Hallo,

ok, das leuchtet mir ein, dass es ihn da beim Deserialisieren wirft...

Aber wie kann ich das umgehen?

Ich muss da -1 stehen haben, sonst bekomme ich probleme, wenn ich mit einer Foreach Schleife über meine Klasse gehe...

Sorry, steh etwas aufm Schlauch.

Gruß

49.485 Beiträge seit 2005
vor 13 Jahren

Hallo mipa_acc,

wie wärs mit einer if-Abfrage (oder bedingten Bewertung) im Getter von Current? Beachte dazu aber bitte [Hinweis] Wie poste ich richtig? Punkt 1.1.1.

Davon abgesehen ist das Verhalten beim Abruf von Current, bei einem Enumerator der vor dem ersten Element steht, laut Doku undefiniert. Das heißt, es kann passieren, was will. Es ist die Aufgabe des Benutzers des Enumerators mit allem zu rechnen, also auch mit einer Exception. Aber ok, der Benutzer ist hier der (De-)Serialisierer und der kennt die Doku nicht. 😃

herbivore

M
mipa_acc Themenstarter:in
318 Beiträge seit 2006
vor 13 Jahren

Alles klar!

Vielen Dank. Dann komm ich klar.

Gruß