[.net] (de)serialisatie geeft foute waarden terug

Pagina: 1
Acties:
  • 123 views sinds 30-01-2008
  • Reageer

  • Tyf
  • Registratie: December 2002
  • Laatst online: 28-11 20:18
Ik ben momenteel bezig wat gegevens weg te schrijven naar een binaire file.
De gegevens zijn wat klassen die ik serialiseer en weg schrijf naar een bestand
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public static void saveStateBIN(Object obj)
        {
            Type currentObjectType = obj.GetType();
            StateObject objectState = new StateObject();

            string filename = currentObjectType.Name + ".state";

            objectState.Name = currentObjectType.Name.ToString();

            findMembers(obj, objectState);

            //to bin file
            Stream str = File.OpenWrite(filename);

            // * TODO: aanpassingen staan in objectstate en in file, bij inladen problemen dat ze niet meer ingelezen worden??
             
            BinaryFormatter formatter = new BinaryFormatter();
            formatter.Serialize(str, objectState);
            str.Close();
        }



Hierna wil ik het weer inlezen via volgende code
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
                  public static void loadStateBIN(string path, Object cont)
        {
            if (File.Exists(path))
            {
                Stream str = File.OpenRead(path);
                BinaryFormatter formatter = new BinaryFormatter();
                StateObject stateObject = (StateObject)formatter.Deserialize(str);

                //* TODO uitlezen geeft andere resultaten, prop 39 = text
                // in bin file staat ook echt het juiste resultaat

                setLastState(cont, stateObject);

                str.Close();
            }
        }


stateObject bevat op het moment van inlezen dus totaal andere waarden dan er in zouden moeten staan (de standaard waarden die de serialiseerde klassen initieel hebben).
Maar wanneer ik het bin bestand open in text editor kan ik toch echt zien dat de textvelden bijvoorbeeld "BOE" bevatten en wanneer ik de binaire weer inlees staat er terug "BA" in de instantie van het binaire bestand.

Is er iemand die een gelijkaardig probleem heeft gehad? Want ik snap er niks meer van. Veel fout kan ik toch niet doen, het staat in het binaire bestand zoals het moet, maar het inlezen loopt fout.

Help :)

Verwijderd

Is property 39 niet stiekem read only? Dan is 'ie niet te deserializen...

  • Tyf
  • Registratie: December 2002
  • Laatst online: 28-11 20:18
stomme vraag misschien, maar hoe zet je iets op read only of terug op write.
Het gaat hier om een klasse die zelf gemaakt is met niks anders dan value = "boe" bijvoorbeeld
Die wordt geserialiseerd en daarna weer ge deserialiseerd.

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
    public class ObjectProperty
    {
        private string name;
        private object propertyValue;

        public ObjectProperty(String name, object value)
        {
            this.name = name;
            this.propertyValue = value;
        }

        public string Name
        {
            get { return name; }
            set {name = value; }
        }

        public object PropertyValue
        {
            get { return propertyValue; }
            set { propertyValue = value; }
        }
    }

[ Voor 54% gewijzigd door Tyf op 04-03-2007 20:29 ]


  • EfBe
  • Registratie: Januari 2000
  • Niet online
Ik zou toch echt gaan checken of je wel het juiste bestand inleest.

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


  • whoami
  • Registratie: December 2000
  • Laatst online: 00:54
Verwijderd schreef op zondag 04 maart 2007 @ 20:22:
Is property 39 niet stiekem read only? Dan is 'ie niet te deserializen...
Serialization (binary & soap) gaat niet kijken naar properties, maar naar de fields.

https://fgheysels.github.io/


  • Tyf
  • Registratie: December 2002
  • Laatst online: 28-11 20:18
Ja uren zitten debuggen maar idd dat juist niet ...
Was iets dat ik dus zeker was dat juist was. Leer het nooit zoveelste keer dat ik denk dat iets in orde is en het niet is. positief punt is dat ik geen ezel ben, want die stoot zich geen 2 keer aan dezelfde steen :)

Nu het was geen verloren moeite ondertussen mooi kunnen refactoren wat zeker nodig was.

Het werkt nu goed :)

[ Voor 31% gewijzigd door Tyf op 04-03-2007 21:36 ]


  • whoami
  • Registratie: December 2000
  • Laatst online: 00:54
Wat was het nu ? De verkeerde file ingelezen ?

https://fgheysels.github.io/


  • Tyf
  • Registratie: December 2002
  • Laatst online: 28-11 20:18
Sorry was idd niet duidelijk. Het was idd niet de juiste file. Ik was totaal vergeten dat er nog een testfile was waar ik hardcoded naar verwees. Alles 100 keer overlopen, nadat de file geopend was dus nooit gezien dat het niet de juist file was :( was zo zeker dat het geen andere file kon zijn ai ai ai

Verwijderd

whoami schreef op zondag 04 maart 2007 @ 21:32:
Serialization (binary & soap) gaat niet kijken naar properties, maar naar de fields.
Private fields moeten wel degelijk een standaard setter hebben wil je ze kunnen deserializen.

  • whoami
  • Registratie: December 2000
  • Laatst online: 00:54
Verwijderd schreef op zondag 04 maart 2007 @ 21:54:
[...]
Private fields moeten wel degelijk een standaard setter hebben wil je ze kunnen deserializen.
Nee, zoals ik al zei, wordt er bij binary & soap serialization niet gekeken naar properties, maar zijn het de fields die geserializeerd worden.
Test het maar uit:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[Serializable]
public class TestSerialize
{
        private string _a;
        private int _b;

        public void SetValues(string a, int b)
        {
            _a = a;
            _b = b;
        }

        public string GetA()
        {
            return _a;
        }

        public int GetB()
        {
            return _b;
        }
}


code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
private void button1_Click(object sender, EventArgs e)
{
            TestSerialize s = new TestSerialize ();
            s.SetValues ("test", 5);

            FileStream fs = new FileStream (@"c:\temp\serializetest.bla", FileMode.Create, FileAccess.Write);

            BinaryFormatter bf = new BinaryFormatter ();
            bf.Serialize (fs, s);
            fs.Close ();

}

private void button2_Click(object sender, EventArgs e)
{
            FileStream fs = new FileStream (@"c:\temp\serializetest.bla", FileMode.Open, FileAccess.Read);
            BinaryFormatter bf = new BinaryFormatter ();
            object o = bf.Deserialize (fs);
            TestSerialize s = o as TestSerialize;
            if( s != null )
            {
                Console.WriteLine (s.GetA ());
                Console.WriteLine (s.GetB ().ToString ());
            }
            fs.Close ();
}

https://fgheysels.github.io/


  • EfBe
  • Registratie: Januari 2000
  • Niet online
klopt, properties zijn eigenlijk 2 methods en die worden niet geserialized, alleen de private members.

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


Verwijderd

zit nu ook met serialisatie
mijn vraag is.. kun je ook in de class zelf serialiseren of moet je het altijd van buiten af doen?
ik zie bij codeproject, google en hier..
de class die geserialiseerd word, door een andere class uitgevoerd wordt.

want als ik het intern doe krijg ik allemaal melding waar ik niet uit kom..

  • whoami
  • Registratie: December 2000
  • Laatst online: 00:54
Waarom zou je het binnen de klasse zelf willen doen ?
Hoe doe je het ?

Wat als je het zo doet:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[Serializable]
public class MySelfSerializingClass
{
    private int _test;

    ...

    public void Serialize( string fileName )
    {
         FileStream fs = new FileStream (fileName, FileMode.Create, FileAccess.Write);
         BinaryFormatter f = new BinaryFormatter ();
         f.Serialize (fs, this);
    }

    public void Deserialize( string fileName )
    {
         FileStream fs = new FileStream (fileName, FileMode.Open, FileAccess.Read);
         BinaryFormatter f = new BinaryFormatter ();
         SerializeableTest tmp = (SerializeableTest)f.Deserialize (fs);
         this._test = tmp._test;
        }
}

Het jammerlijke is natuurlijk dat het deserializen een beetje omslachtig is, aangezien je ieder field zult moeten kopieren. Jammer genoeg ondersteunt C# geen copy constructors. Echter, je zou dit wel kunnen generiek maken door gebruik te maken van reflection. (Ieder field overlopen, en de waarde kopieren).

https://fgheysels.github.io/


Verwijderd

het zal niet gaan werken ..

in die class staat een list en enum dus.. zal apparte class gemaakt moeten worden..
Pagina: 1