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.
LVL 1
Newt6398Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

gbzhhuCommented:
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
0
Newt6398Author Commented:
Not too sure where abouts you are but it's tomorrow now here in UK, thanks for the help.
0
gbzhhuCommented:
I am in UK too down south.  I just got to work ;-) will get back to you in a short while
0
Cloud Class® Course: MCSA MCSE Windows Server 2012

This course teaches how to install and configure Windows Server 2012 R2.  It is the first step on your path to becoming a Microsoft Certified Solutions Expert (MCSE).

gbzhhuCommented:
Do you specifically require to save data in binary, I use xml
0
Newt6398Author Commented:
I will be saving in binary but I assume an example for either will do, I can fettle it if it's XML. Cheers.
0
gbzhhuCommented:
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]

0
gbzhhuCommented:
Remember your classes must have default constructor for xml serialization to succeed
0
Newt6398Author Commented:
Cheers I'll give it a go this evening when I get home. Thanks for the help.
0
Newt6398Author Commented:
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();
                        }
                  }

            }

      }

}
0
illusioSoftware Architect / Team LeaderCommented:
Does the student type has a default constructor???
Otherwise serialisation will fail on that one.

Peter
0
Newt6398Author Commented:
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.
0
gbzhhuCommented:
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


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

Cheers.
0
gbzhhuCommented:
Ok posting here and emailed the source to you


using System;
using System.Collections;
using System.Collections.Specialized;

namespace serialization
{
      [Serializable]
      public class SerializationTest
      {
            public SerializationTest(){}
            
            private ArrayList students = new ArrayList();
            
            public ArrayList Students
            {
                  get { return this.students; }
                  set { this.students = value; }
            }      

            private string title;
            public string Title
            {
                  get { return this.title; }
                  set { this.title = value; }
            }
      }

      [Serializable]
      public class Student
      {
            public Student(){}

            private string name;
            private int age;

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

            public int Age
            {
                  get { return this.age; }
                  set { this.age = value; }
            }
      }

}


//This code if from a form.  In a click event of a button

            private void button1_Click(object sender, System.EventArgs e)
            {
                  SerializationTest ds = new SerializationTest();
                  ds.Title = "List of strudents";
                  Student s = new Student();
                  s.Name = "Hassan";
                  s.Age = 36;
                  Student s2 = new Student();
                  s2.Name = "Graig";
                  s2.Age = 21;
                  Student s3 = new Student();
                  s3.Name = "Sarah";
                  s3.Age = 26;
                  ds.Students.Add(s);
                  ds.Students.Add(s2);
                  ds.Students.Add(s3);

                  this.SerializeData(ds);
            }

            private void SerializeData(SerializationTest ds)
            {
                  string theFile = @"c:\test.dat";
                  FileStream fs;

                  try
                  {
                        BinaryFormatter bf = new BinaryFormatter();
                        File.Delete(theFile);
                        fs = File.Open(theFile, FileMode.CreateNew, FileAccess.Write, FileShare.ReadWrite);
         
                        bf.Serialize(fs, ds);
                        fs.Close();
                  }
                  catch (Exception ex)
                  {
                        MessageBox.Show(ex.ToString());
                  }
            }


// The form class must include these using directives

using System.Runtime.Serialization.Formatters.Binary;
using System.IO;

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Newt6398Author Commented:


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.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C#

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.