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

DataTable and Serialization

I have a GeneralDataTable class that inherits from the DataTable.  In my GeneralDataTable I have some private variables and public propties.

In my form I declare a GeneralDataTable.  Then via remoting I call my middle tier and I have it return a GeneralDataTable with Data.  However when I do this the data comes back but none of my properties that I created are what I set them to in the middle tier.  How do I add my private vairables to also be serialized.

0
curtis591
Asked:
curtis591
  • 11
  • 8
  • 3
  • +1
1 Solution
 
Jeffr0Commented:
Private Variables won't Serialize.

Public will, though.
0
 
Jeffr0Commented:
Declaring them as "Friend" might-- I haven't been able to verify that though.
0
 
gregoryyoungCommented:
you can also write a custom serialization if you want to do this ...

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconCustomSerialization.asp

I am assuming you are using a XML serialization (shallow)

Private variables and properties are all serialized. In binary serialization, both the private variables and properties are serialized. This is known as deep serialization, as opposed to shallow serialization in XML serialization (which only serializes the public variables and properties).
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
Jeffr0Commented:
Cool stuff, gregoryyoung... I'm glad to know this.
0
 
curtis591Author Commented:
I tried Friend And Public And they did not work
Here a a snippet of my code


Imports System.Data.SqlClient
Imports System.Data.Odbc
Imports System.ComponentModel
Imports System.Runtime.Serialization
'Imports System.Runtime.Globalization

<Serializable()> _
Public Class GeneralDataTable
    Inherits DataTable

public cSQLStatement  as string

Public Property SQLStatement() As String
        Get
            Return cSQLStatement
        End Get
        Set(ByVal Value As String)
            cSQLStatement = Value
        End Set
 End Property

Public Sub New(ByVal info As SerializationInfo, ByVal context As StreamingContext)
        MyBase.New(info, context)
    End Sub

    Public Sub New()
        MyBase.new()
    End Sub

End Class

--SQLClass Code
Public Class SqlCode
  public Function getData() as generaldataTable
     dim gdt as new generalDataTable
     gdt.SQLStatement = "select ....."
     return  mybase.execute_query(gdt)
  end function
End Class


--Calling Form
dim x as new sqlCode
dim mytable as generaldatatable
mytable = x.getData()



0
 
gregoryyoungCommented:
what is not going accross the SqlStatement ?
0
 
curtis591Author Commented:
yeah it is says nothing.  Yet the datatable has its data
0
 
gregoryyoungCommented:
the problem has has to do with the fact that you are using default serializastion on a class that supports ISerializable. So its running the custom serialization. The link above will show you how to implement custom stuff (you override do your stuff then call your base's serialization methods)

0
 
gregoryyoungCommented:
from the text in MSDN

To restore the state of the object, simply retrieve the values of the variables from SerializationInfo using the names used during serialization. If the base class implements ISerializable, the base constructor should be called to allow the base object to restore its variables.

When you derive a new class from one that implements ISerializable, the derived class must implement both the constructor as well as the GetObjectData method if it has variables that need to be serialized. The code example below shows how this is done using the MyObject class shown previously.

Do not forget to call the base class in the deserialization constructor; if this is not done, the constructor on the base class will never be called, and the object will not be fully constructed after deserialization.

0
 
curtis591Author Commented:
for a datatable there is not mybase.getOjectData method.
0
 
gregoryyoungCommented:
DataTable implements ISerializable

Public Class DataTable
   Inherits MarshalByValueComponent
   Implements IListSource, ISupportInitialize, ISerializable

ISerializable defines a method GetObjectData

the base class does not need to have a method named this ...

cast mybase into an ISerializable to call the method var = directcast(mybase, ISerializable) var.GetObjectData() ...
0
 
gregoryyoungCommented:
you may actually have to write a wrapper instead of inherit in this case ...

0
 
curtis591Author Commented:
what do you mean by a wrapper
0
 
gregoryyoungCommented:
n/m reimplement the ISerializable interface ... use the direct cast as said before on the base ...

so your class will implement ISerializable even though the base already does.
0
 
curtis591Author Commented:
when I go
Public Class generalDataTable
   inherits Datatable
   implements Iserializable

I get an error say I can not implement it
0
 
gregoryyoungCommented:
intresting .... I just did it in C# without problem ...

anyways I found the issue ... here is some info.. http://weblogs.asp.net/fbouma/archive/2003/11/12/37199.aspx
0
 
curtis591Author Commented:
I got things working now.  I don't inherit the datatable but simply make it a property on my class and the implement the Iserializable interface.  
 
  Then weird thing know is that when a record in my datatable insertes or updates it retrieves my the updated record back out so I have the primary key. However though when do this without remoting I bind the datatable to a grid.  Insert a record and after the update the primary key displays in the grid.  When I do this via remoting the updated record is in the datatable but it does not update the grid.  why would this be?
0
 
ihenryCommented:
To phrase gregory comment taken from msdn,
When inherit from a serialized class that implements ISerializable, the derived class must implement both the constructor as well as the GetObjectData method. And the custom properties also need to be serialized.

<Serializable()> _
Public Class GeneralDataTable
    Inherits DataTable

    Private cSQLStatement  as string

    Public Property SQLStatement() As String
        Get
            Return cSQLStatement
        End Get
        Set(ByVal Value As String)
            cSQLStatement = Value
        End Set
    End Property

    ' this constructor is called during serialization
    Public Sub New(ByVal info As SerializationInfo, ByVal context As StreamingContext)
        MyBase.New(info, context)
        cSQLStatement   = info.GetString("SQLStatement")
    End Sub

    Public Sub New()
        MyBase.new()
    End Sub

    ' this method is called during deserialization
    Public Overrides Sub GetObjectData(ByVal info As SerializationInfo, ByVal context As StreamingContext)
        info.AddValue("SQLStatement", cSQLStatement, GetType(String))
        MyBase.GetObjectData(info, context)
    End Sub

End Class
0
 
gregoryyoungCommented:
ihenry that is true ... however the issue here is a VB limitation ...

it is met through a private implementation within datatable and vb is not capable of reimplementing an interface ... therefor using a property is correct in this case. I would most likely however not use that everywhere, I would probably use it only during serialization and then provide a transformation to the preferred view (inheriting from DataTable)
0
 
gregoryyoungCommented:
is further help needed with this ?
0
 
curtis591Author Commented:
I change the class so it has a property of  a datatable.  Then this class implements the Iserializable interface.  HOwever for some reason when I do this If I add a couple of rows to the table from my user interface and I pass the datatable back to the middle tier to update the It does not add to the rows to my sql table as it looks like in the datatable thinks they are unchanged and I am unsure what would be causing it.  Could it be that I need to Seralize all of the properties inside the datatable as well?
0
 
gregoryyoungCommented:
are you using binary serialization ?

try this ...

<Serializable()> _
Public Class GeneralDataTable

    Private cSQLStatement  as string
    private Data as DataTable

    Public Property SQLStatement() As String
        Get
            Return cSQLStatement
        End Get
        Set(ByVal Value As String)
            cSQLStatement = Value
        End Set
    End Property

    Public Property DataTable() As DataTable
        Get
            Return Data
        End Get
        Set(ByVal Value As DataTable)
            DataTable = Value
        End Set
    End Property

    Public Sub New()
    End Sub
End Class

let the default serialization do it ... and yes I think you are missing some data when you go to do it ... I would call the datatables serialization routine from within yours if you want to implement it that way.
0
 
curtis591Author Commented:
That worked.  

 As a side question.  In my updates I retrieve the record updated back out same with the inserts so I get primary key info, etc.  When I do this with non remoting and bind the my GeneralDataTable to the grid and insert a record and press save the ID column in the grid populates with the primary key that was inserted.  When I tell it to use remoting this does not work.

I tell it to use remoting by the following line
RemotingConfiguration.RegisterWellKnownClientType(GetType(CreditSQL.CreditSQL), "http://ips07601/mydirectory/CreditSQL.soap")
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 11
  • 8
  • 3
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now