Newt6398
asked on
Serilize Arraylist along with a class.
Hi Experts,
I'm new to c# and have probably gone around things the wrong way but this is what I need to do and have managed so far.
I will have quite a few classes that I want to put into a file for retrieval later on, so I decided to create a class to deal with the collection of all my classes and serialization to filestream so I can store all classes into one file. So I basically end up with (pseudo):
class Class1
{
string data1
string data 2
}
class Class2
{
string data1
string data 2
}
class Class3
{
string data1
string data 2
}
class theStore
{
//Stores arrays of the other class objects
ArrayList Class1
ArrayList Class2
ArrayList Class3
//methods to add, get objects, return array counts etc used only by the storeControlClass......
}
class storeControlClass
{
theStore storage = new theStore;
public void addObject()
{
storage.addObj(object FromClass, theStoreArray)
}
//Etc, I hope your following the drift of this :-)
We then have methods to load theStore from file or save using serilization etc and other methods to pass on the getting of objects from theStore, counts of a particular array etc.
}
Now this all works well the way I have it setup I just have the slight problem of no data from the arraylists being stored when I serialize them. I looked into the binary file and I can see everything is as should be but no data. I understand that i should be serilizing my arrays on their own rather than within a class is there a way to serialise the class with the ArrayLists or to serilize the arrayLists within the class then serialize the class (I've tried that but to no avail and don't want to create more files/filestreams).
Any ideas how I can get that data in the arrayLists to be stored along with the serilization of the class they are in??????
Thanks.
I'm new to c# and have probably gone around things the wrong way but this is what I need to do and have managed so far.
I will have quite a few classes that I want to put into a file for retrieval later on, so I decided to create a class to deal with the collection of all my classes and serialization to filestream so I can store all classes into one file. So I basically end up with (pseudo):
class Class1
{
string data1
string data 2
}
class Class2
{
string data1
string data 2
}
class Class3
{
string data1
string data 2
}
class theStore
{
//Stores arrays of the other class objects
ArrayList Class1
ArrayList Class2
ArrayList Class3
//methods to add, get objects, return array counts etc used only by the storeControlClass......
}
class storeControlClass
{
theStore storage = new theStore;
public void addObject()
{
storage.addObj(object FromClass, theStoreArray)
}
//Etc, I hope your following the drift of this :-)
We then have methods to load theStore from file or save using serilization etc and other methods to pass on the getting of objects from theStore, counts of a particular array etc.
}
Now this all works well the way I have it setup I just have the slight problem of no data from the arraylists being stored when I serialize them. I looked into the binary file and I can see everything is as should be but no data. I understand that i should be serilizing my arrays on their own rather than within a class is there a way to serialise the class with the ArrayLists or to serilize the arrayLists within the class then serialize the class (I've tried that but to no avail and don't want to create more files/filestreams).
Any ideas how I can get that data in the arrayLists to be stored along with the serilization of the class they are in??????
Thanks.
I have done this successfully but you will have to wait till tomorrow when I get to work. Post a comment here so i get a reminder email at work and I will send you code of how to do it
ASKER
Not too sure where abouts you are but it's tomorrow now here in UK, thanks for the help.
I am in UK too down south. I just got to work ;-) will get back to you in a short while
Do you specifically require to save data in binary, I use xml
ASKER
I will be saving in binary but I assume an example for either will do, I can fettle it if it's XML. Cheers.
Ok, try this first
insert this line
[System.Xml.Serialization. XmlInclude ( typeof( Class1 ) )]
[System.Xml.Serialization. XmlInclude ( typeof( Class2 ) )]
[System.Xml.Serialization. XmlInclude ( typeof( Class3 ) )]
before the class theStore so it looks like this
[Serializable]
[System.Xml.Serialization. XmlInclude ( typeof( Class1 ) )]
[System.Xml.Serialization. XmlInclude ( typeof( Class2 ) )]
[System.Xml.Serialization. XmlInclude ( typeof( Class3 ) )]
class theStore
{
}
Then declare the arrays like this
[XmlArrayItem(ElementName= "Class1 Item", IsNullable=false, Type = typeof(Class1), Namespace = "http://www.SomeURL.com")]
[XmlArray(ElementName= "Class1 Array")]
ArrayList Class1
[XmlArrayItem(ElementName= "Class2 Item", IsNullable=false, Type = typeof(Class2), Namespace = "http://www.SomeURL.com")]
[XmlArray(ElementName= "Class2 Array")]
ArrayList Class2
[XmlArrayItem(ElementName= "Class3 Item", IsNullable=false, Type = typeof(Class3), Namespace = "http://www.SomeURL.com")]
[XmlArray(ElementName= "Class3 Array")]
ArrayList Class3
"http://www.SomeURL.com" can be any URL (I am not sure if it can be left blank)
Serilaize theStore class like this
public bool Save()
{
bool saved = false;
StreamWriter file = null;
try
{
// Serialize the object to Xml.
XmlSerializer writer = new XmlSerializer(this.GetType ());
file = new StreamWriter(@"C:\test.xml ");
// Write the serialized object out to a file.
writer.Serialize(file, this);
saved = true;
}
catch (Exception ex)
{
saved = false;
}
finally
{
if (file != null)
{
// Make sure we always close the file.
file.Close();
}
}
return saved;
}
What difference does that make? you have to reference System.Xml.Serialization obviously (in class theStore) and you have to mark all classes as [Serializable]
insert this line
[System.Xml.Serialization.
[System.Xml.Serialization.
[System.Xml.Serialization.
before the class theStore so it looks like this
[Serializable]
[System.Xml.Serialization.
[System.Xml.Serialization.
[System.Xml.Serialization.
class theStore
{
}
Then declare the arrays like this
[XmlArrayItem(ElementName=
[XmlArray(ElementName= "Class1 Array")]
ArrayList Class1
[XmlArrayItem(ElementName=
[XmlArray(ElementName= "Class2 Array")]
ArrayList Class2
[XmlArrayItem(ElementName=
[XmlArray(ElementName= "Class3 Array")]
ArrayList Class3
"http://www.SomeURL.com" can be any URL (I am not sure if it can be left blank)
Serilaize theStore class like this
public bool Save()
{
bool saved = false;
StreamWriter file = null;
try
{
// Serialize the object to Xml.
XmlSerializer writer = new XmlSerializer(this.GetType
file = new StreamWriter(@"C:\test.xml
// Write the serialized object out to a file.
writer.Serialize(file, this);
saved = true;
}
catch (Exception ex)
{
saved = false;
}
finally
{
if (file != null)
{
// Make sure we always close the file.
file.Close();
}
}
return saved;
}
What difference does that make? you have to reference System.Xml.Serialization obviously (in class theStore) and you have to mark all classes as [Serializable]
Remember your classes must have default constructor for xml serialization to succeed
ASKER
Cheers I'll give it a go this evening when I get home. Thanks for the help.
ASKER
Am just getting a blank file containg XML tag, that's all. So the code must be working only the data not writing to it.
Here's my full code, it's a tad messy now after so much faffinf about with it:
using System;
using System.IO;
using System.Runtime.Serializati on;
using System.Runtime.Serializati on.Formatt ers.Binary ;
using System.Xml.Serialization;
using System.Collections;
namespace student_test
{
/// <summary>
/// Summary description for storeClasses.
/// </summary>
///
[Serializable]
public class storeClasses
{
[XmlArrayItem(ElementName= "studentsArrayItem", IsNullable=false, Type = typeof(students), Namespace = "http://www.codershome.com")]
[XmlArray(ElementName= "studentsArray")]
private ArrayList studentsArray = new ArrayList();
public storeClasses()
{
studentsArray = new ArrayList();
}
public ArrayList StudentsArray
{
set {studentsArray = value; }
get {return studentsArray; }
}
public void addObject(object theObject, theArray selectArray)
{
switch (selectArray)
{
case theArray.student:
studentsArray.Add(theObjec t);
break;
default:
break;
}
}
public object getObject(int id, theArray fromArray)
{
switch (fromArray)
{
case theArray.student:
return studentsArray[id];
break;
default:
return null;
break;
}
}
public int getCount(theArray arrayToCount)
{
switch(arrayToCount)
{
case theArray.student: return studentsArray.Count;
break;
default:
break;
}
return 0;
}
}
public enum theArray { student, teacher }
public class storeControl
{
protected storeClasses currentStore = new storeClasses();
private string theFile;
public storeControl(string CurrentFile)
{
theFile = CurrentFile;
}
public storeControl()
{
}
public string CurrentFile
{
set {theFile = value; }
get {return theFile; }
}
public object getObject(int id, theArray objectFromArray)
{
loadArrays();
return currentStore.getObject(id, objectFrom Array);
}
public int getCount(theArray arrayToCount)
{
loadArrays();
return currentStore.getCount(arra yToCount);
}
public void saveObject(object theObject, theArray toArray)
{
//loadArrays();
currentStore.addObject(the Object, toArray);
saveArrays();
}
private void loadArrays()
{
storeClasses makeStore = new storeClasses();
if(File.Exists(theFile))
{
BinaryFormatter bf = new BinaryFormatter();
FileStream fs = File.Open(theFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
if (fs.Length > 0)
{
currentStore.StudentsArray = (ArrayList)bf.Deserialize( fs);
}
else
{
currentStore = new storeClasses();
}
fs.Close();
}
else
{
currentStore = new storeClasses();
}
}
private void saveArrays()
{
/*
ArrayList theSerial = new ArrayList();
theSerial = currentStore.StudentsArray ;
BinaryFormatter bf = new BinaryFormatter();
File.Delete(theFile);
FileStream fs = File.Open(theFile, FileMode.CreateNew, FileAccess.Write, FileShare.ReadWrite);
bf.Serialize(fs, theSerial);
fs.Close();
*/
object theSerial;
bool saved = false;
StreamWriter file = null;
theSerial = currentStore;
try
{
// Serialize the object to Xml.
XmlSerializer writer = new XmlSerializer(this.GetType ());
file = new StreamWriter(@theFile);
// Write the serialized object out to a file.
writer.Serialize(file, theSerial);
saved = true;
}
catch (Exception ex)
{
saved = false;
}
finally
{
if (file != null)
{
// Make sure we always close the file.
file.Close();
}
}
}
}
}
Here's my full code, it's a tad messy now after so much faffinf about with it:
using System;
using System.IO;
using System.Runtime.Serializati
using System.Runtime.Serializati
using System.Xml.Serialization;
using System.Collections;
namespace student_test
{
/// <summary>
/// Summary description for storeClasses.
/// </summary>
///
[Serializable]
public class storeClasses
{
[XmlArrayItem(ElementName=
[XmlArray(ElementName= "studentsArray")]
private ArrayList studentsArray = new ArrayList();
public storeClasses()
{
studentsArray = new ArrayList();
}
public ArrayList StudentsArray
{
set {studentsArray = value; }
get {return studentsArray; }
}
public void addObject(object theObject, theArray selectArray)
{
switch (selectArray)
{
case theArray.student:
studentsArray.Add(theObjec
break;
default:
break;
}
}
public object getObject(int id, theArray fromArray)
{
switch (fromArray)
{
case theArray.student:
return studentsArray[id];
break;
default:
return null;
break;
}
}
public int getCount(theArray arrayToCount)
{
switch(arrayToCount)
{
case theArray.student: return studentsArray.Count;
break;
default:
break;
}
return 0;
}
}
public enum theArray { student, teacher }
public class storeControl
{
protected storeClasses currentStore = new storeClasses();
private string theFile;
public storeControl(string CurrentFile)
{
theFile = CurrentFile;
}
public storeControl()
{
}
public string CurrentFile
{
set {theFile = value; }
get {return theFile; }
}
public object getObject(int id, theArray objectFromArray)
{
loadArrays();
return currentStore.getObject(id,
}
public int getCount(theArray arrayToCount)
{
loadArrays();
return currentStore.getCount(arra
}
public void saveObject(object theObject, theArray toArray)
{
//loadArrays();
currentStore.addObject(the
saveArrays();
}
private void loadArrays()
{
storeClasses makeStore = new storeClasses();
if(File.Exists(theFile))
{
BinaryFormatter bf = new BinaryFormatter();
FileStream fs = File.Open(theFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
if (fs.Length > 0)
{
currentStore.StudentsArray
}
else
{
currentStore = new storeClasses();
}
fs.Close();
}
else
{
currentStore = new storeClasses();
}
}
private void saveArrays()
{
/*
ArrayList theSerial = new ArrayList();
theSerial = currentStore.StudentsArray
BinaryFormatter bf = new BinaryFormatter();
File.Delete(theFile);
FileStream fs = File.Open(theFile, FileMode.CreateNew, FileAccess.Write, FileShare.ReadWrite);
bf.Serialize(fs, theSerial);
fs.Close();
*/
object theSerial;
bool saved = false;
StreamWriter file = null;
theSerial = currentStore;
try
{
// Serialize the object to Xml.
XmlSerializer writer = new XmlSerializer(this.GetType
file = new StreamWriter(@theFile);
// Write the serialized object out to a file.
writer.Serialize(file, theSerial);
saved = true;
}
catch (Exception ex)
{
saved = false;
}
finally
{
if (file != null)
{
// Make sure we always close the file.
file.Close();
}
}
}
}
}
Does the student type has a default constructor???
Otherwise serialisation will fail on that one.
Peter
Otherwise serialisation will fail on that one.
Peter
ASKER
Yes it does, everything works fine the serialization and all, the classes seems to work fine, but just no data at all is store from arrayList, when I add another property to my theStore class of string then that info is stored. I could post the whole thing or put it on the web if it is necessary.
gbzhhu if you have a binary version of your above code I would be interested in seeing that. It may be that I am just totally missing something out here, I can understand why it may not be possible to normally serilize an arrayList but there's got to be a way to do it even if it means creating my own serializing class and do everything that way. This is something that would take like 5 minutes in Delphi, I just can't believe there's such a powerful feature as serilization but with the inability to serilize an arrayList within a class.
Craig.
gbzhhu if you have a binary version of your above code I would be interested in seeing that. It may be that I am just totally missing something out here, I can understand why it may not be possible to normally serilize an arrayList but there's got to be a way to do it even if it means creating my own serializing class and do everything that way. This is something that would take like 5 minutes in Delphi, I just can't believe there's such a powerful feature as serilization but with the inability to serilize an arrayList within a class.
Craig.
Craig,
I didn't read all the code because I came to the point where you applied the XML attributes to the private field
[XmlArrayItem(ElementName= "studentsArrayItem", IsNullable=false, Type = typeof(students), Namespace = "http://www.codershome.com")]
[XmlArray(ElementName= "studentsArray")]
private ArrayList studentsArray = new ArrayList();
The attributes need to be applied to the public property of the field as xml serialization does not serialize private fields, so you need
[XmlArrayItem(ElementName= "studentsArrayItem", IsNullable=false, Type = typeof(students), Namespace = "http://www.codershome.com")]
[XmlArray(ElementName= "studentsArray")]
public ArrayList StudentsArray
{
set {studentsArray = value; }
get {return studentsArray; }
}
Try that
Also, if you put the project on the web I would be able to work on it abd see what is happening quicker, plus I would attempt to get the binary serialization working
I didn't read all the code because I came to the point where you applied the XML attributes to the private field
[XmlArrayItem(ElementName=
[XmlArray(ElementName= "studentsArray")]
private ArrayList studentsArray = new ArrayList();
The attributes need to be applied to the public property of the field as xml serialization does not serialize private fields, so you need
[XmlArrayItem(ElementName=
[XmlArray(ElementName= "studentsArray")]
public ArrayList StudentsArray
{
set {studentsArray = value; }
get {return studentsArray; }
}
Try that
Also, if you put the project on the web I would be able to work on it abd see what is happening quicker, plus I would attempt to get the binary serialization working
Ok, I have put together an example of serializing the array (binary), which is pretty easy (not too much code) do I paste it all in here or is there another way I can the code to you. Would probably be right hing to do to post it here for future reference
ASKER
Thanks, am in work so will look at it tonight. Can post to craig@codershome.com.
Cheers.
Cheers.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
I can’t believe how stupid I was being, (arrrr). I had created the constructor as follows for student class:
Class student(string fName, string lName) //etc
I wasn’t assigning them here.
Thank you very much for your help, it took your example for me to realize this. I would give more points on EE but I do not have them.
Once again thank you.
Craig Stewart.