none
Detection of object type before deserialization possible? RRS feed

  • Question

  • I am serializing several different types of objects, then sending them between two applications. The process all works fine, but I need to be able to know which type and object is *before* I deserialize it for casting. Is there a method of getting the type of an object before deserializing it, or can the deserialization process detect this and cast accordingly?

    Tuesday, March 12, 2019 9:57 PM

Answers

  • Hi,

    I tried some methods, it seems that the type can be read only after deserialization.

    Imports System.IO
    Imports System.Runtime.Serialization.Formatters.Binary
    
    Public Class Form1
    
        <Serializable>
        Public Class person
    
        End Class
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            '    Dim inputList As List(Of String) = New List(Of String)() From {
            '    "a",
            '    "b",
            '    "c"
            '}
    
            'Dim inputList As String = "123"
    
            Dim inputList As New person
            Using fsWriter As FileStream = New FileStream("test.tmp", FileMode.Create, FileAccess.Write)
                Dim bf As BinaryFormatter = New BinaryFormatter()
                bf.Serialize(fsWriter, inputList)
            End Using
        End Sub
    
        Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
            Dim outputList
    
            Using fsReader As FileStream = New FileStream("test.tmp", FileMode.Open, FileAccess.Read)
                Dim bf As BinaryFormatter = New BinaryFormatter()
                outputList = bf.Deserialize(fsReader)
            End Using
            MsgBox(outputList.GetType.ToString)
        End Sub
    End Class
    

    Best Regards,

    Alex


    MSDN Community Support Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • Marked as answer by Sam Marrocco Wednesday, May 15, 2019 2:01 PM
    Wednesday, March 13, 2019 5:45 AM

All replies

  • Let's say each class is setup something like this

    <Serializable()>
    Public Class EmailItem
        Public Property Id() As Integer
        Public Property FromAddress() As String
        Public Property Password() As String
    End Class

    And the save looks like this for the above.

    Public Function Save() As Boolean
    
        mHasException = False
    
        Dim bf As New BinaryFormatter
        Try
    
            Using fs As New FileStream(FileName, FileMode.Create)
    
                For Each EmailInfo In List
                    bf.Serialize(fs, EmailInfo)
                Next
    
                fs.Close()
    
            End Using
        Catch ex As Exception
            mHasException = True
            mLastException = ex
        Finally
            If Not (bf Is Nothing) Then
                bf = Nothing
            End If
        End Try
    
        Return IsSuccessFul
    
    End Function

    Then on top of this we have yet another class and save method placed into the same file. When loading you test for the type, below is only testing for one type but the if statement then for two classes would turn into a if/else etc.

    Public Function Load() As Boolean
    
        If Not FileExists() Then
            mHasException = False
        End If
    
        mHasException = False
    
        Dim bf As New BinaryFormatter
        Dim item As Object
    
        Dim fs As New FileStream(FileName, FileMode.OpenOrCreate)
    
        Try
    
            Do
                item = bf.Deserialize(fs)
    
                If item.GetType Is GetType(EmailItem) Then
                    List.Add(CType(item, EmailItem))
                End If
    
            Loop While fs.Position < fs.Length - 1
    
        Catch ex As Exception
            mHasException = True
            mLastException = ex
        Finally
            fs.Close()
            If Not (bf Is Nothing) Then
                bf = Nothing
            End If
        End Try
    
        Return IsSuccessFul
    
    End Function
    

    So if the other class was Manager we end up with

    If item.GetType Is GetType(EmailItem) Then
        List.Add(CType(item, EmailItem))
    ElseIf item.GetType() Is GetType(Manager) Then
        '
        '
        '
    End If
    The above is a basic example and note things like mHasException and IsSuccessFiul are custom properties I created that are not needed for this sort of operation.


    Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

    NuGet BaseConnectionLibrary for database connections.

    StackOverFlow
    profile for Karen Payne on Stack Exchange

    Tuesday, March 12, 2019 10:17 PM
    Moderator
  • I am serializing several different types of objects, then sending them between two applications. The process all works fine, but I need to be able to know which type and object is *before* I deserialize it for casting. Is there a method of getting the type of an object before deserializing it, or can the deserialization process detect this and cast accordingly?

    WCF does this for you using XML serialization, a datacontract, where it serializes the known type,  deserializes it and casts it back to its known type between the WCF client program and the WCF service program. One application/program  can be the WCF client and the other application/program can be the WCF service. 


    Wednesday, March 13, 2019 5:29 AM
  • Hi,

    I tried some methods, it seems that the type can be read only after deserialization.

    Imports System.IO
    Imports System.Runtime.Serialization.Formatters.Binary
    
    Public Class Form1
    
        <Serializable>
        Public Class person
    
        End Class
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            '    Dim inputList As List(Of String) = New List(Of String)() From {
            '    "a",
            '    "b",
            '    "c"
            '}
    
            'Dim inputList As String = "123"
    
            Dim inputList As New person
            Using fsWriter As FileStream = New FileStream("test.tmp", FileMode.Create, FileAccess.Write)
                Dim bf As BinaryFormatter = New BinaryFormatter()
                bf.Serialize(fsWriter, inputList)
            End Using
        End Sub
    
        Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
            Dim outputList
    
            Using fsReader As FileStream = New FileStream("test.tmp", FileMode.Open, FileAccess.Read)
                Dim bf As BinaryFormatter = New BinaryFormatter()
                outputList = bf.Deserialize(fsReader)
            End Using
            MsgBox(outputList.GetType.ToString)
        End Sub
    End Class
    

    Best Regards,

    Alex


    MSDN Community Support Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • Marked as answer by Sam Marrocco Wednesday, May 15, 2019 2:01 PM
    Wednesday, March 13, 2019 5:45 AM