Results 1 to 10 of 10

Thread: Serialize a collection of objects

  1. #1

    Thread Starter
    I wonder how many charact
    Join Date
    Feb 2001
    Location
    Savage, MN, USA
    Posts
    3,704

    Serialize a collection of objects

    I'm trying to serialize a collection of a certain type of class...

    I keep getting a Reflection error when I attempt to serialize with the code below... with the two classes below. I can sucessfully serialze the SalesRep class, but not its collection class... I CAN SUCESSFULLY serialize it to a BinaryFormatter ...and retrieve.. but not when using XMLSerializer...

    VB Code:
    1. Dim gwhiz As Xml.Serialization.XmlSerializer = New Xml.Serialization.XmlSerializer(GetType(SalesRepCollection))
    2.         Dim rep1 As SalesRep = New SalesRep(12, "John", "Labrizzi")
    3.         Dim rep2 As SalesRep = New SalesRep(5, "Eddie", "Gasser")
    4.         Dim myReps As SalesRepCollection = New SalesRepCollection()
    5.         myReps.Add(rep1)
    6.         myReps.Add(rep2)
    7.  
    8.        dim fs as System.IO.FileStream = New System.IO.FileStream("C:\sales.xml", IO.FileMode.Create)
    9.         gwhiz.Serialize(fs, myReps)
    10.         fs.Close()

    Here is the SalesRep Class:
    VB Code:
    1. <Serializable()> Public Class SalesRep
    2.  
    3.     Public Sub New()
    4.  
    5.     End Sub
    6.  
    7.     Public Sub New(ByVal RepID As Int32, ByVal RepFirstName As String, _
    8.     ByVal RepLastName As String, Optional ByVal RepMiddleName As String = Nothing)
    9.  
    10.         sRepID = RepID
    11.         sRepFName = RepFirstName
    12.         sRepMName = RepMiddleName
    13.         sRepLName = RepLastName
    14.     End Sub
    15.  
    16.     Private sRepID As Int32
    17.     Private sRepFName As String
    18.     Private sRepMName As String
    19.     Private sRepLName As String
    20.  
    21.     Public Property SalesRepId() As Int32
    22.         Get
    23.             Return sRepID
    24.         End Get
    25.         Set(ByVal Value As Int32)
    26.             sRepID = Value
    27.         End Set
    28.     End Property
    29.     Public Property FirstName() As String
    30.         Get
    31.             Return sRepFName
    32.         End Get
    33.         Set(ByVal Value As String)
    34.             sRepFName = Value
    35.         End Set
    36.     End Property
    37.     Public Property MiddleName() As String
    38.         Get
    39.             Return sRepMName
    40.         End Get
    41.         Set(ByVal Value As String)
    42.             sRepMName = Value
    43.         End Set
    44.     End Property
    45.     Public Property LastName() As String
    46.         Get
    47.             Return sRepLName
    48.         End Get
    49.         Set(ByVal Value As String)
    50.             sRepLName = Value
    51.         End Set
    52.     End Property

    Here's the SalesRep collection class:
    VB Code:
    1. Option Strict Off
    2. <Serializable()> Public Class SalesRepCollection
    3.     Inherits System.Collections.CollectionBase
    4.  
    5.  
    6.     Public Function Add(ByVal Salesman As SalesRep) As Integer
    7.         ' Invokes Add method of the List object to add a object.
    8.         Return List.Add(Salesman)
    9.  
    10.     End Function
    11.     Public Sub New()
    12.  
    13.     End Sub
    14.  
    15.     Public Sub Remove(ByVal index As Integer)
    16.  
    17.         If index > Count - 1 Or index < 0 Then
    18.  
    19.         Else
    20.             ' Invokes the RemoveAt method of the List object.
    21.             List.RemoveAt(index)
    22.         End If
    23.     End Sub
    24.  
    25.     '
    26.     Public Function GetItem(ByVal index As Integer) As SalesRep
    27.         Return CType(List.Item(index), SalesRep)
    28.     End Function
    29.  
    30.    
    31.     Public Sub SetItem(ByVal index As Integer, ByVal SalesMan As SalesRep)
    32.  
    33.         List.Item(index) = CType(SalesMan, SalesRep)
    34.     End Sub
    Last edited by nemaroller; Apr 24th, 2003 at 02:44 PM.

  2. #2

  3. #3
    Your Ad Here! Edneeis's Avatar
    Join Date
    Feb 2000
    Location
    Moreno Valley, CA (SoCal)
    Posts
    7,339
    If you get the innerException for the reflection error you find that it is because you have not exposed a default accessor in the collection. Instead of using your get/set methods try adding this item property and everything should work then.

    VB Code:
    1. Default Public Property Item(ByVal index As Integer) As SalesRep
    2.         Get
    3.             Return CType(List.Item(index), SalesRep)
    4.         End Get
    5.         Set(ByVal Value As SalesRep)
    6.             list.Item(index) = Value
    7.         End Set
    8.     End Property

  4. #4

    Thread Starter
    I wonder how many charact
    Join Date
    Feb 2001
    Location
    Savage, MN, USA
    Posts
    3,704
    You're correct, I had not declared a default public property...

    And of course, it works now....

    And equally of course, I am grateful.... you are not just the man, you are the GOD!

  5. #5

    Thread Starter
    I wonder how many charact
    Join Date
    Feb 2001
    Location
    Savage, MN, USA
    Posts
    3,704
    Here's a stumper....

    The salesman class and collection class represented above are part of a bigger project....

    The top level is actually a collection of invoices...
    Each invoice has a customer, salesrep, date, etc

    HERE'S THE TRICKY PART:

    Each invoice has a collection of invoice items (chair, sofa, etc)


    Now, I had made an InvoiceItem Class which holds the properties of a single item... for example, Chair would include the styleID, manufacturer ID, width, length, height....

    To hold a collection of those InvoiceITems... I made an InvoiceItemCollection class....

    What I want to be able to do is STICK that collection of InvoiceITems into the Invoice class...

    something like Dim InvoiceItems() As InvoiceItemCollection

    So that when I save the collection of Invoices (InvoiceCollection), I am actually saving each invoice, and each invoice item inside each invoice element....
    Code:
    <InvoiceCollection>
       <Invoice>
          <DateofSale>
          <SalesRep>
             <Fname>]
              <Lname>
          <Customer>
              <Fname>
               <Lname>
         <InvoiceItem>
                   <Name>
                   <ManufacturerID>
                   <Length>
                   <Width>
          </InvoiceItem>
          <InvoiceItem>
                   <Name>
                   <ManufacturerID>
                   <Length>
                   <Width>
          </InvoiceItem>
        </Invoice>
       <Invoice>
          .........'repeat for another invoice
       </Invoice>
    </InvoiceCollection>
    So you see, its a collection of a collection...
    and I don't know if I should make Invoice inherit a collectionbase to hold the invoiceItems (which I couldn't get to work well), or simply Dim someVariable() As InvoiceCollection() , which did work when saving to file.... and since it worked saving to file... it has something to do with the default property setting...

  6. #6
    Your Ad Here! Edneeis's Avatar
    Join Date
    Feb 2000
    Location
    Moreno Valley, CA (SoCal)
    Posts
    7,339
    Did you get the second thing to work or no?

    Actually it seems you should have two collectio types: InvoiceCollection and InvoiceItemCollection.

    InvoiceCollection holds a group of Invoices
    Each Invoice object has an InvoiceItemCollection which holds a group of InvoiceItem objects.

  7. #7

    Thread Starter
    I wonder how many charact
    Join Date
    Feb 2001
    Location
    Savage, MN, USA
    Posts
    3,704
    Yes, I got everything to work... it makes great XML.... only problem now is trying to imbed a collection within a collection... (invoiceitems within invoices)....

    I do have these classes:

    InvoiceCollection
    Invoice
    InvoiceItemCollection
    InvoiceItem

    As of right now, I'm just using

    Private invItemCollection As InvoiceItemCollection = New InvoiceItemCollection()

    within the Invoice class....

    problem is... it doesn't write the invoiceitemcollection to XML...


    VB Code:
    1. Imports DinesenClientLibrary.InvoiceItem
    2. Imports DinesenClientLibrary.Customer
    3. Imports DinesenClientLibrary.SalesRep
    4. Imports DinesenClientLibrary.InvoiceItemCollection
    5.  
    6. <Serializable()> Public Class Invoice
    7.     Private invID As Int32
    8.     Private invNo As Int32
    9.     Private invDate As Date
    10.     Private sClass As Int32  'sales class special order, stock,etc
    11.     Private InvCust As Customer
    12.     Private InvItems As InvoiceItemCollection = New InvoiceItemCollection()
    13.     Private sRep As SalesRep
    14.     Private ClearedPO As Boolean 'ready for PO, authorized by eddie
    15.  
    16.     Public Sub New()
    17.  
    18.     End Sub
    19.  
    20.     Public Sub New(ByVal InvoiceCustomer As Customer, ByVal invoiceDate As Date, ByVal invoiceItems As InvoiceItemCollection, ByVal salesRep As SalesRep)
    21.         InvItems = invoiceItems
    22.         invDate = invoiceDate
    23.         InvCust = InvoiceCustomer
    24.         sRep = salesRep
    25.  
    26.     End Sub
    27.  
    28.    Public ReadOnly Property Item(ByVal a As Int32) As InvoiceItem
    29.         Get
    30.             Return CType(InvItems.GetItem(a), InvoiceItem)
    31.         End Get
    32.     End Property

  8. #8
    Your Ad Here! Edneeis's Avatar
    Join Date
    Feb 2000
    Location
    Moreno Valley, CA (SoCal)
    Posts
    7,339
    Either it needs an XMLArray attribute for that property or its because you are exposing it as an item property of a non-collection. If its the latter try changing it to this:

    VB Code:
    1. Public ReadOnly Property InvoiceItems() As InvoiceItemCollection
    2.         Get
    3.             Return InvItems
    4.         End Get
    5.     End Property

    Or it might need both, not sure.

    And if you don't want to allow the user to add items then you can handle that in the InvoiceItemsCollection itself.

  9. #9

    Thread Starter
    I wonder how many charact
    Join Date
    Feb 2001
    Location
    Savage, MN, USA
    Posts
    3,704

    Talking

    I will get around to responding to this... I just don't have that source code with me right now...

  10. #10

    Thread Starter
    I wonder how many charact
    Join Date
    Feb 2001
    Location
    Savage, MN, USA
    Posts
    3,704
    Thanks Edneesis... took a look at it this morning, took about five minutes to implement... and it works...

    The namespace argument of the XMLArrray attribute makes little sense to me... but i guess it doesn't matter..
    Last edited by nemaroller; Apr 29th, 2003 at 10:17 AM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width