VB6->DOT NET :: What is the dot Net code for this old method?

109 Views Asked by At

I'm building an application that has its data on a custom data structure array with multiple variables and child arrays of other custom structures...

I need to be able to save and load that data to file and Serialization did work untill I needed to load and save that same file on multiple applications.

I had to use old VB6 technique to reach my goal. Is there a way to write this in more recent code?

On the examples below, Persons is an array of a structure containing all sorts of info on persons, including sub arrays of other structures of different sizes for their kids, pets, etc.

Save code:

        '// Get file number
        Dim fn As Integer = FreeFile()
        '// Opens the file for binary write
        FileOpen(fn, FileName, OpenMode.Binary, OpenAccess.Write)
        '// Get persons count
        Dim pc As Integer = Persons.GetUpperBound(0)
        '// Write persons count
        FilePut(fn, pc)
        '// Write Persons
        FilePut(fn, Persons)
        '// Close the file
        FileClose(fn)

Load code:

        '// Get file number
        Dim fn As Integer = FreeFile()
        '// Opens the file for binary read
        FileOpen(fn, FileName, OpenMode.Binary, OpenAccess.Read)
        '// Get persons count
        Dim pc As Integer
        '// Read persons count
        FileGet(fn, pc)
        '// Prepare Persons array for it
        Persons = Nothing
        ReDim Persons(0 To pc)
        '// Read Persons
        FileGet(fn, Persons)
        '// Close the file
        FileClose(fn)

EDIT with additional information:

When using serialization this was that I was using. I've simplified things to make it easier to reproduce without exposing excessive info. Here's an example of 2 applications I've written as testing.

My structures and variable are as below. Each parent may have 0 or more kids:

'// Parent structure
<Serializable> Private Structure Parents
    Dim Name As String
    Dim Age As Integer
    Dim Kids() As Kids
End Structure
'// Kid structure
<Serializable> Private Structure Kids
    Dim Name As String
    Dim Age As Integer
    Dim GoesInScool As Boolean
End Structure
Private Persons() As Parents

To save I'm using this code:

'// Gets BinaryFormatter
Dim BF As New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter()
'// Makes new Memorystream
Dim MS As New System.IO.MemoryStream()
'// Serialize to Memorystream
BF.Serialize(MS, Persons)
'// Writes the content to file
My.Computer.FileSystem.WriteAllBytes(FileName, MS.GetBuffer(), False)

To load I'm using this code:

'// Loads file to a byte()
Dim bytes As Byte() = My.Computer.FileSystem.ReadAllBytes(FileName)
'// Gets BinaryFormatter
Dim BF As New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter()
'// Reads data
Persons = DirectCast(BF.Deserialize(New System.IO.MemoryStream(bytes)), Parents())

I've made 2 applications: StructureSaver_App_A and StructureSaver_App_B. They were made from scratch but I've copied exactly the same code on all functions.

When I save on StructureSaver_App_A and try to load on StructureSaver_App_B I get this error code: System.Runtime.Serialization.SerializationException: 'Unable to find assembly 'StructureSaver_App_A, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.'

When I save on StructureSaver_App_B and try to load on StructureSaver_App_A I get this error code: System.Runtime.Serialization.SerializationException: 'Unable to find assembly 'StructureSaver_App_B, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.'

Loading on StructureSaver_App_A a file saved on StructureSaver_App_A works perfectly fine. Loading on StructureSaver_App_B a file saved on StructureSaver_App_B works perfectly fine.

Thanks

1

There are 1 best solutions below

1
Felix Almesberger On

You try to serialize an object from one application and deserialize it from another. Even when those objects seem to be the same, because of the same properties etc, they are not. Because they are in different assemblies or namespaces.

As you said you are serializing an object of type ApplicationOne.MyObject and deserialize it as ApplicationTwo.MyObject. The binary formatter will fail because within that binary data there is the name of the original type and this cannot be found as you are in a different context where this type does not exist. You need to extract those shared classes in an extra library and share it between your applications by referencing it. Or move to a (value)serialization that does not care about namespaces. E.g. JSON.