Solved

DataTable and Serialization

Posted on 2004-04-30
25
950 Views
Last Modified: 2008-02-26
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
Comment
Question by:curtis591
  • 11
  • 8
  • 3
  • +1
25 Comments
 
LVL 2

Expert Comment

by:Jeffr0
ID: 10960103
Private Variables won't Serialize.

Public will, though.
0
 
LVL 2

Expert Comment

by:Jeffr0
ID: 10960136
Declaring them as "Friend" might-- I haven't been able to verify that though.
0
 
LVL 37

Expert Comment

by:gregoryyoung
ID: 10960193
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
 
LVL 2

Expert Comment

by:Jeffr0
ID: 10960306
Cool stuff, gregoryyoung... I'm glad to know this.
0
 
LVL 6

Author Comment

by:curtis591
ID: 10960394
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
 
LVL 37

Expert Comment

by:gregoryyoung
ID: 10960480
what is not going accross the SqlStatement ?
0
 
LVL 6

Author Comment

by:curtis591
ID: 10960493
yeah it is says nothing.  Yet the datatable has its data
0
 
LVL 37

Expert Comment

by:gregoryyoung
ID: 10960573
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
 
LVL 37

Expert Comment

by:gregoryyoung
ID: 10960616
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
 
LVL 6

Author Comment

by:curtis591
ID: 10960706
for a datatable there is not mybase.getOjectData method.
0
 
LVL 37

Expert Comment

by:gregoryyoung
ID: 10960753
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
Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

 
LVL 37

Expert Comment

by:gregoryyoung
ID: 10960901
you may actually have to write a wrapper instead of inherit in this case ...

0
 
LVL 6

Author Comment

by:curtis591
ID: 10960925
what do you mean by a wrapper
0
 
LVL 37

Expert Comment

by:gregoryyoung
ID: 10961037
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
 
LVL 6

Author Comment

by:curtis591
ID: 10961072
when I go
Public Class generalDataTable
   inherits Datatable
   implements Iserializable

I get an error say I can not implement it
0
 
LVL 37

Expert Comment

by:gregoryyoung
ID: 10961759
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
 
LVL 6

Author Comment

by:curtis591
ID: 10963165
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
 
LVL 20

Expert Comment

by:ihenry
ID: 10972396
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
 
LVL 37

Expert Comment

by:gregoryyoung
ID: 10974885
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
 
LVL 37

Expert Comment

by:gregoryyoung
ID: 11036596
is further help needed with this ?
0
 
LVL 6

Author Comment

by:curtis591
ID: 11042269
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
 
LVL 37

Accepted Solution

by:
gregoryyoung earned 250 total points
ID: 11042337
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
 
LVL 6

Author Comment

by:curtis591
ID: 11044181
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

Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Suggested Solutions

A while ago, I was working on a Windows Forms application and I needed a special label control with reflection (glass) effect to show some titles in a stylish way. I've always enjoyed working with graphics, but it's never too clever to re-invent …
It’s quite interesting for me as I worked with Excel using vb.net for some time. Here are some topics which I know want to share with others whom this might help. First of all if you are working with Excel then you need to Download the Following …
This demo shows you how to set up the containerized NetScaler CPX with NetScaler Management and Analytics System in a non-routable Mesos/Marathon environment for use with Micro-Services applications.
Polish reports in Access so they look terrific. Take yourself to another level. Equations, Back Color, Alternate Back Color. Write easy VBA Code. Tighten space to use less pages. Launch report from a menu, considering criteria only when it is filled…

707 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

14 Experts available now in Live!

Get 1:1 Help Now