Link to home
Start Free TrialLog in
Avatar of Newt6398
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.
Avatar of gbzhhu
gbzhhu
Flag of United Kingdom of Great Britain and Northern Ireland image

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
Avatar of Newt6398
Newt6398

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
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]

Remember your classes must have default constructor for xml serialization to succeed
Cheers I'll give it a go this evening when I get home. Thanks for the help.
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.Serialization;
using System.Runtime.Serialization.Formatters.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(theObject);
                              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,objectFromArray);

            }

            public int getCount(theArray arrayToCount)
            {
                  loadArrays();
                  return currentStore.getCount(arrayToCount);
            }

            public void saveObject(object theObject, theArray toArray)
            {
                  //loadArrays();
                  currentStore.addObject(theObject, 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();
                        }
                  }

            }

      }

}
Avatar of illusio
Does the student type has a default constructor???
Otherwise serialisation will fail on that one.

Peter
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.
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


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
Thanks, am in work so will look at it tonight. Can post to craig@codershome.com.

Cheers.
ASKER CERTIFIED SOLUTION
Avatar of gbzhhu
gbzhhu
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial


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.