Toon posts:

[C#] Class serializen naar Xml

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik ben met een klein projectje bezig, waarin ik een aantal instellingen heb. Om met deze instellingen te werken heb ik een class geschreven, welk een viertal instance variablen bevat, en een viertal properties. Tevens is een constructor. Dat ziet er dus ongeveer zo uit:

code:
1
2
3
4
5
6
7
8
9
private string ipaddress;       // The IP address of the database server
private int port;           // The port at which the database runs
private string username;        // The username with which to connect to the database
private byte[] password;        // The password associated with the user

public string IPAddress { get { return ipaddress; } set { ipaddress = value; } }
public int Port { get { return port; } set { port = value; } }
public string Username { get { return username; } set { username = value; } }
public string Password { <code> }


Om deze instellingen persistent te maken wil ik dus de class serializen naar Xml, en dat in een bestandje zetten. Maar zoals te zien is er ook een password veld, en het is natuurlijk niet de bedoeling dat dat zo uit het bestandje te lezen valt. Dus om dat op te lossen dacht ik, ik maak gebruik van wat encryptie.

Zo gezegd zo gedaan, ik maak in de constructor twee ICryptoTransform objecten aan, eentje om te encoderen, en eentje om te decoderen. Die zijn dan ook weer instance variablen van de class.

Vervolgens zet ik in de property Password code om het password te coderen en te decoderen bij de get en set stukken.

Dat werkt op zich goed, alleen is het probleem nu dat op het moment dat ik de class ga serializen hij niet de instance variablen, maar de waarden van de properties in het bestand op slaat. Met als gevolg dat het wachtwoord alsnog in plain text in het Xml documentje staat.

Kortom, hij moet de instance variablen opslaan, en niet de properties. Hoe kan ik er voor zorgen dat ie dat doet?

  • whoami
  • Registratie: December 2000
  • Laatst online: 01:57
Allereerst, waarom wil je je passwoord ook decoderen? Dat is toch voor niks nodig?

https://fgheysels.github.io/


Verwijderd

Topicstarter
whoami schreef op 20 juni 2003 @ 16:31:
Allereerst, waarom wil je je passwoord ook decoderen? Dat is toch voor niks nodig?
;) 'k moet dat password wel weer ergens kunnen gebruiken, namelijk bij het maken van een connectie met de database. En ik denk niet dat die mijn Rijndael encrypted wachtwoordje slikt.

  • whoami
  • Registratie: December 2000
  • Laatst online: 01:57
De Xml Serializer slaat ook instance members op hoor, alleen beperkt hij zich tot de public variables en properties:
XML serialization is the process of converting an object's public properties and fields to a serial format (in this case, XML) for storage or transport. Deserialization re-creates the object in its original state from the XML output. You can thus think of serialization as a way of saving the state of an object into a stream or buffer. For example, ASP.NET uses the XmlSerializer class to encode XML Web service messages.

https://fgheysels.github.io/


Verwijderd

Topicstarter
whoami schreef op 20 juni 2003 @ 16:36:
De Xml Serializer slaat ook instance members op hoor, alleen beperkt hij zich tot de public variables en properties:


[...]
Ehmz, wat is in dat geval dan 't verschil tussen de properties en de instance variablen. Immers als ik de instance variablen public maak, dan kan je dus op twee manieren de boel veranderen, via die public instance variablen en via de public properties. Dat is toch niet echt handig lijkt me?

  • EfBe
  • Registratie: Januari 2000
  • Niet online
ISerializable implementeren. (System.Runtime.Serialization).

Je implementeert dan een private constructor en een public method. Je kunt in de public method de waarde meegeven die geserializeerd moet worden en bij het deserializeren in de private constructor kun je dan je waarde decoderen.

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


Verwijderd

Topicstarter
EfBe schreef op 20 juni 2003 @ 16:48:
ISerializable implementeren. (System.Runtime.Serialization).

Je implementeert dan een private constructor en een public method. Je kunt in de public method de waarde meegeven die geserializeerd moet worden en bij het deserializeren in de private constructor kun je dan je waarde decoderen.
Ehmz, wat is 't nut van een private constructor? Dan kan een object toch nooit aangemaakt worden? Of ben ik nou gek?

Verwijderd

Topicstarter
Hmmz, 'k heb ffies gekeken naar de documentatie van die ISerializable interface, maar 'k volg 't niet echt eigenlijk.

't enige wat ik eigenlijk wil is dat in 't XML documentje 't password gecodeerd wordt opgeslagen, en binnen 't programma moet ik er gewoon normaal mee kunnen werken. Als normale, leesbare strings dus.

  • whoami
  • Registratie: December 2000
  • Laatst online: 01:57
Door die ISerializable interface moet je een GetObjectData method implementeren. In die method moet je een bepaald object opvullen met de info die jij dan geserializeerd wilt hebben.
Althans, dat is wat ik er van maak.

https://fgheysels.github.io/


  • Crazy D
  • Registratie: Augustus 2000
  • Laatst online: 14-08 12:38

Crazy D

I think we should take a look.

Verwijderd schreef op 20 juni 2003 @ 16:27:
Met als gevolg dat het wachtwoord alsnog in plain text in het Xml documentje staat.
Dat heb ik quick'n'dirty (of niet ;)) opgelost door te zorgen dat de variabele password altijd een ge-encrypt wachtwoord bevat. In de property-get decrypt ik t wachtwoord, en in de propert-set encrypt ik 'm.

[ Voor 14% gewijzigd door Crazy D op 20-06-2003 17:41 ]

Exact expert nodig?


  • whoami
  • Registratie: December 2000
  • Laatst online: 01:57
Crazy D schreef op 20 June 2003 @ 17:40:
[...]

Dat heb ik quick'n'dirty (of niet ;)) opgelost door te zorgen dat de variabele password altijd een ge-encrypt wachtwoord bevat.
De topicstarter's private member 'passWord' bevat afaik toch ook altijd een ge-encrypted password.
Het is de property password die ervoor zorgt dat het passwoord ge-encrypted wordt of gedecrypted wordt. Naargelang het ge-get of geset wordt.

https://fgheysels.github.io/


Verwijderd

Topicstarter
whoami schreef op 20 juni 2003 @ 17:43:
[...]


De topicstarter's private member 'passWord' bevat afaik toch ook altijd een ge-encrypted password.
Het is de property password die ervoor zorgt dat het passwoord ge-encrypted wordt of gedecrypted wordt. Naargelang het ge-get of geset wordt.
En dat is op zich wel prettig, want dan valt er binnen 't programma prima mee te werken. Alleen slikt die XmlSerializer dus alleen de public instance variablen en public properties. En dus komt 't password alsnog in plain text in 't XML documentje te staan.

  • whoami
  • Registratie: December 2000
  • Laatst online: 01:57
Verwijderd schreef op 20 June 2003 @ 17:45:
[...]


En dat is op zich wel prettig, want dan valt er binnen 't programma prima mee te werken. Alleen slikt die XmlSerializer dus alleen de public instance variablen en public properties. En dus komt 't password alsnog in plain text in 't XML documentje te staan.
Dus, toch nog eens naar die Iserializable interface kijken. ;)

https://fgheysels.github.io/


Verwijderd

Topicstarter
whoami schreef op 20 June 2003 @ 17:45:
[...]


Dus, toch nog eens naar die Iserializable interface kijken. ;)
Mjah, dat heb 'k dus ook al wel gedaan, alleen volg 'k er de ballen van. Private constructoren, internal sealed classes, classes die een instance variable hebben van hun eigen type. Vage shit allemaal ;).

  • whoami
  • Registratie: December 2000
  • Laatst online: 01:57
Verwijderd schreef op 20 June 2003 @ 17:46:
[...]


Mjah, dat heb 'k dus ook al wel gedaan, alleen volg 'k er de ballen van. Private constructoren, internal sealed classes, classes die een instance variable hebben van hun eigen type. Vage shit allemaal ;).
In dat voorbeeld is dat zo inderdaad, maar dat hoeft daarvoor bij jou nog zo niet te zijn geloof ik.

Wat je wel zult moeten doen is die GetDataObject method implementeren. 'k Heb er zelf wel nog geen ervaring mee.

Dat die class in dat voorbeeld een variable heeft van z'n eigen type komt gewoon omdat het een Singleton is. (Voor meer informatie: zie het singleton design pattern).

[ Voor 14% gewijzigd door whoami op 20-06-2003 17:48 ]

https://fgheysels.github.io/


Verwijderd

Topicstarter
whoami schreef op 20 juni 2003 @ 17:47:
[...]


In dat voorbeeld is dat zo inderdaad, maar dat hoeft daarvoor bij jou nog zo niet te zijn geloof ik.

Wat je wel zult moeten doen is die GetDataObject method implementeren. 'k Heb er zelf wel nog geen ervaring mee.

Dat die class in dat voorbeeld een variable heeft van z'n eigen type komt gewoon omdat het een Singleton is. (Voor meer informatie: zie het singleton design pattern).
Hmmz, 'k heb nu die GetObjectData methode geïmplementeerd, maar bij het serializen neemt ie nog steeds de public properties. Hoe zit dat precies?

edit:

Sterker nog, die hele methode wordt nooit aangeroepen.

[ Voor 7% gewijzigd door Verwijderd op 20-06-2003 18:08 ]


Verwijderd

Topicstarter
Hmmz, volgens mij kan je ISerializable alleen gebruiken bij Binary Serialization, en dus niet bij XML Serialization. Maar jah, bij Binary Serialization wordt 't een stuk lastig om te controleren of 't ook daadwerkelijk gecodeerd opgeslagen wordt.

edit:

Hmmz, het is nu gelukt met Binary Serialization. Was wel iets meer gekloot, maar goed het werkt in ieder geval. En 't wachtwoord wordt gecodeerd opgeslagen. Perfect dus. Nooit verwacht dat 't nog moeilijk zou zijn. Allemaal bedankt voor jullie hulp in ieder geval :).

[ Voor 39% gewijzigd door Verwijderd op 20-06-2003 20:41 ]


  • EfBe
  • Registratie: Januari 2000
  • Niet online
Verwijderd schreef op 20 juni 2003 @ 16:50:
Ehmz, wat is 't nut van een private constructor? Dan kan een object toch nooit aangemaakt worden? Of ben ik nou gek?
Je hebt een EXTRA constructor die private is en 2 parameters krijgt.

voorbeeldje:
Java:
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#region Class Member Declarations
private EntityFieldsCollection      _fields;
private string              _name;
private IDBTable            _targetTable;
private EntityRelationCollection    _relations;
private ArrayList           _primaryKeyFields;
private SortedList          _uniqueConstraints;
#endregion

/// <summary>
/// CTor
/// </summary>
/// <param name="name">CLS Compliant name for the entity</param>
/// <param name="targetTable">Target table for this entity, i.e. the database representation of the entity.</param>
public EntityDefinition(string name, IDBTable targetTable)
{
    _fields = new EntityFieldsCollection(this);
    _targetTable = null;
    _name = name;
    _relations = new EntityRelationCollection();
    _primaryKeyFields = new ArrayList();
    _uniqueConstraints = new SortedList();
    PopulateUsingTargetTable(targetTable);
}


/// <summary>
/// Private CTor for deserialization
/// </summary>
/// <param name="info"></param>
/// <param name="context"></param>
private EntityDefinition(SerializationInfo info, StreamingContext context)
{
    // deserialize the data back into this instance.
    _fields = (EntityFieldsCollection)info.GetValue("_fields", typeof(EntityFieldsCollection));
    _targetTable = (IDBTable)info.GetValue("_targetTable", typeof(IDBTable));
    _relations = (EntityRelationCollection)info.GetValue("_relations", typeof(EntityRelationCollection));
    _primaryKeyFields = (ArrayList)info.GetValue("_primaryKeyFields", typeof(ArrayList));
    _uniqueConstraints = (SortedList)info.GetValue("_uniqueConstraints", typeof(SortedList));
    _name = info.GetString("_name");

    // rewire events.
    for(int i=0;i<_fields.Count;i++)
    {
        _fields[i].EntityFieldDefinitionChanged += new EventHandler(OnEntityFieldDefinitionChanged);
    }
}


/// <summary>
/// ISerializable member. 
/// </summary>
/// <param name="info"></param>
/// <param name="context"></param>
public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
{
    info.AddValue("_fields", _fields, typeof(EntityFieldsCollection));
    info.AddValue("_targetTable", _targetTable, typeof(IDBTable));
    info.AddValue("_relations", _relations, typeof(EntityRelationCollection));
    info.AddValue("_primaryKeyFields", _primaryKeyFields, typeof(ArrayList));
    info.AddValue("_uniqueConstraints", _uniqueConstraints, typeof(SortedList));
    info.AddValue("_name", _name);
}

//...

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


  • EfBe
  • Registratie: Januari 2000
  • Niet online
Verwijderd schreef op 20 June 2003 @ 19:56:
Hmmz, volgens mij kan je ISerializable alleen gebruiken bij Binary Serialization, en dus niet bij XML Serialization. Maar jah, bij Binary Serialization wordt 't een stuk lastig om te controleren of 't ook daadwerkelijk gecodeerd opgeslagen wordt.
Als je nu een SOAP formatter gebruikt, dan serialize je alles in 4 regels code (incl file openen en sluiten) weg. Let op dat XmlSerializer een object is dat niet alleen voor serialization wordt gebruikt maar ook voor databinding. Het kreng staat ook veel minder toe, bv je kunt geen parameters die een type Interface hebben serializen, terwijl de SOAP formatter dat gewoon doet. Kostte me vorige week 2 uur. :)

SOAP serializen:
Java:
1
2
3
4
FileStream output = new FileStream(destinationFileName, FileMode.Create);
SoapFormatter formatter = new SoapFormatter();
formatter.Serialize(output, this);
output.Close();


Deserializen voorbeeldje:
Java:
1
2
3
4
FileStream input = new FileStream(projectPathFileName, FileMode.Open);
SoapFormatter formatter = new SoapFormatter();
projectToReturn = (Project)formatter.Deserialize(input);
input.Close();

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


Verwijderd

Topicstarter
EfBe schreef op 20 June 2003 @ 22:46:
[...]

Als je nu een SOAP formatter gebruikt, dan serialize je alles in 4 regels code (incl file openen en sluiten) weg. Let op dat XmlSerializer een object is dat niet alleen voor serialization wordt gebruikt maar ook voor databinding. Het kreng staat ook veel minder toe, bv je kunt geen parameters die een type Interface hebben serializen, terwijl de SOAP formatter dat gewoon doet. Kostte me vorige week 2 uur. :)

SOAP serializen:
Java:
1
2
3
4
FileStream output = new FileStream(destinationFileName, FileMode.Create);
SoapFormatter formatter = new SoapFormatter();
formatter.Serialize(output, this);
output.Close();


Deserializen voorbeeldje:
Java:
1
2
3
4
FileStream input = new FileStream(projectPathFileName, FileMode.Open);
SoapFormatter formatter = new SoapFormatter();
projectToReturn = (Project)formatter.Deserialize(input);
input.Close();
Mjah, dat heb 'k nu dus ook, alleen dan met een BinaryFormatter. Werkt op zich ook prima :).

  • EfBe
  • Registratie: Januari 2000
  • Niet online
De binaryformatter werkt alleen goed in .net 1.1. Hij heeft een bug in .net 1.0 waardoor je structs in arraylists e.d. niet kunt deserializen. Hij is wel veel sneller dan die soap serializer :) maar je wilde xml, vandaar :P

[ Voor 3% gewijzigd door EfBe op 21-06-2003 10:02 ]

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


  • whoami
  • Registratie: December 2000
  • Laatst online: 01:57
Verwijderd schreef op 20 June 2003 @ 19:56:
Hmmz, volgens mij kan je ISerializable alleen gebruiken bij Binary Serialization, en dus niet bij XML Serialization. Maar jah, bij Binary Serialization wordt 't een stuk lastig om te controleren of 't ook daadwerkelijk gecodeerd opgeslagen wordt.
Waarom niet?
Ik heb het net ff getest, en het werkt perfect.
Ik heb een TestClass gemaakt, de ISerializable interface geimplementeerd etc...

En dan mbhv een XmlSerializer serialize en deserialize ik mijn objecten.

https://fgheysels.github.io/


Verwijderd

Topicstarter
whoami schreef op 22 June 2003 @ 10:24:
[...]


Waarom niet?
Ik heb het net ff getest, en het werkt perfect.
Ik heb een TestClass gemaakt, de ISerializable interface geimplementeerd etc...

En dan mbhv een XmlSerializer serialize en deserialize ik mijn objecten.
Maar volgens mij roept ie dan niet die GetObjectData methode aan bij het serializeren, en de private constructor bij het deserializeren. Dat werkt volgens mij alleen bij Binary (of SOAP blijkbaar ook) serializeren/deserializen. 'k heb nog wat System.Diagnostics.Debug.Write() regeltjes er in gezet, en 'k zag niks in m'n debug schermpje, dus volgens mij werkt 't niet.

  • whoami
  • Registratie: December 2000
  • Laatst online: 01:57
Hmmm..... Inderdaad, je hebt gelijk.

Ik heb er nu eens met de debugger door gestapt, en hij komt idd niet in die GetObjectData method.

https://fgheysels.github.io/


  • EfBe
  • Registratie: Januari 2000
  • Niet online
Zoals ik al eerder zei: de XmlSerializer class is niet echt voor serialization. Ik wilde heb ook gebruiken voor het snel van class -> xml te komen maar omdat ik overal interfaces als types gebruik werd dit een nachtmerrie, terwijl de soap formatter het prima doet, m.a.w.: de soap formatter gebruikt de xmlserializer niet.

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

Pagina: 1