• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 350
  • Last Modified:

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.
0
Newt6398
Asked:
Newt6398
  • 8
  • 7
1 Solution
 
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
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
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
 
illusioCommented:
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
 
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

Featured Post

Vote for the Most Valuable Expert

It’s time to recognize experts that go above and beyond with helpful solutions and engagement on site. Choose from the top experts in the Hall of Fame or on the right rail of your favorite topic page. Look for the blue “Nominate” button on their profile to vote.

  • 8
  • 7
Tackle projects and never again get stuck behind a technical roadblock.
Join Now