Deserialization Exception in Another Application RRS feed

  • Question

  • In Visual Basic .NET Framework 4.0 and ASP.NET, I am
    getting exceptions from attempts to deserialize
    instances of classes.

    In simple terms, I can serialize and deserialize
    within one program with good success and without
    difficulty, but if I serialize (to an instance of
    class MemoryStrean to an array of Byte), send the
    results to a second program, and attempt to
    deserialize, then I get the exception.  The Visual
    Basic source code for serialization and
    deserialization in both programs is the same and
    just copied and then compiled.

    In my case, each of the two programs is for a (its
    own) Web page in my Web site, and the serialized
    data goes from the first program to a key-value
    store I wrote (which seems to be working fine) to
    the second program.

    Everything being attempted is quite simple -- e.g.,
    the class whose instances I am serializing and then
    attempting to deserialize is really simple with just
    a few simple properties, each just a simple data
    type -- Int32, String, DateTime, etc.  There is only
    one method, New, and it is simple and just assigns
    simple default values to the properties.

    So, I am building a Web site and doing the
    development on XP SP3 with the latest Microsoft
    updates as of this week.

    In the code for my Web site's 'home page', for
    each newly arriving user, I create a 'session ID'
    from a 'globally unique identifier' (GUID) and
    convert that to data of type String.  So, I get a
    string of 36 simple ASCII characters.  Since I don't
    want to insist that the user's browser accept
    cookies, I send and receive a user's session ID as
    just the value of a hidden field.

    For a user's 'session state' I defined a class
    SSS_session with appropriate properties for the
    relevant data.

    So, what goes to/from my key-value store is a user's
    session ID as a key and that user's session state as
    an instance of my class SSS_session as the value.

    To send to the key-value store, the session ID of
    type String and the session state an instance of
    type SSS_session are each converted to an array of
    Byte.  For the instance of type SSS_session, the
    conversion is via the method Serialize of an
    instance of the class BinaryFormatter as in

         BinaryFormatter.Serialize Method (Stream, Object)


    From then on, each time a Web page gets an HTTP POST
    from a user, the code of the page uses


    to read the user's session ID from its hidden field
    as type String, converts the session ID to an array
    of Byte, sends this array to the key-value store,
    gets back a key-value pair, and then on the value
    uses the method Deserialize in class BinaryFormatter
    to convert back to an instance of class SSS_session.

    Again, all this works fine, round-trip, end to end,
    as long as just one program is executing both the
    methods Serialize and Deserialize.  But when one
    program executes the Serialize, another program,
    with the same source code for all the
    de/serialization, etc. gets an exception trying to
    run the method Deserialize.

    What's wrong?

    Do I need to specify marshal-by-value as in

         Remotable and Nonremotable Objects


    The class whose instances I am de/serializing
    already has

         <Serializable()> Class SPP_session

    and that does specify marshal-by-value?

    As in

         Automatic Deserialization in .NET Framework Remoting


         BinaryFormatter.FilterLevel Property


    I need to specify a "remoting deserialization level"
    of "LOW" or "FULL"?

    As in

         BinaryFormatter.UnsafeDeserialize Method


    I need to use the method


    instead of


    I should put all the code related to
    de/serialization in one Namespace and have all my
    Web pages load that one Namespace?  That is, having
    all the de/serialization work done by just one
    'assembly', that is, the one Namespace, would solve
    the problem?

    Note:  All this software is for inside my server
    farm behind a good firewall from the Internet and
    where all my software trusts all my other software.
    So, if I make a mistake and the code fails, fine; it
    was my fault.  But otherwise I just want the code to
    work with no concerns about 'security'.

    As it is, what appears to be some really severe
    controls and restrictions, to save me from some
    vague issues about security problems I don't have,
    have my Web site development dead in the water.

    Generally, sure, if send data to another program,
    then a lot of goals of 'strong typing' will have to
    be lost and the application software development
    will have to be careful and implement controls of
    its own.  So be it.  But we DO have to send data.

    Gee, guys, what's the sense in serialization if
    can't send the data to another program and there do
    a deserialization?

    Any ideas on what's wrong and how to fix it?

    Saturday, November 24, 2012 11:28 PM

All replies

  • I'm sorry, not sure if I missed it but what exception are you getting exactly?
    Tuesday, November 27, 2012 11:42 PM
  •  Thanks for your interest.

    So, in Visual Basic .NET Framework 4.0 I have

        <Serializable()> _
        Public Class SPP_session

    ' simple properties with just 'value' types
    ' and one simple method New

        End Class

    And I have

        Dim byte_array( 1 ) As Byte

    which I fill from a 'key' via some simple TCP/IP
    sockets from my simple key-value store.
    Then I continue with

    '    MemoryStream Class
    '    http://msdn.microsoft.com/en-us/library/system.io.memorystream(v=vs.100).aspx

    '    MemoryStream Constructor (Byte())
    '    http://msdn.microsoft.com/en-us/library/e55f3s5k(v=vs.100).aspx

        memory_stream = New MemoryStream( byte_array )

    '    Note:  The DirectCast just below is from the
    '    code sample in

    '    BinaryFormatter.Deserialize Method (Stream)
    '    http://msdn.microsoft.com/en-us/library/b85344hz(v=vs.100).aspx

        error_code = 1003

        users_session_state = DirectCast( _
          binary_formatter.Deserialize( memory_stream ), _
          SPP_session )

          return_code = 1002
          message_tag = 1002
          log_message = _
            "Unexpected condition." & _
            " return_code = " & return_code & _
            " Exception thrown." & _
            " error_code = " & error_code & _
            " err.number = " & err.number & _
            " err.source = " & err.source & _
            " err.description = " & err.description
        Call write_log02( _
          site_name, _
          users_IP_address, _
          page_name, _
          routine_name, _
          message_tag, _
          log_message, _
          logging_source_name )

        End Try

    where my little subroutine write_log02 is a simple
    use of the ASP.NET logging functionality.

    As I can tell from the statement

    error_code = 1003

    and the error message that gets written in the block
    Catch, the exception is from the method Deserialize
    in the arguments of the statement DirectCast.

    Yes, I wrote that block Catch before I understood

    Catch ex As Exception

    and then the properties ex.message and ex.source
    which my more recent blocks Catch use.

    So for your question, what exception, I don't know.

    When I was diagnosing the problem and letting the
    exception be caught by ASP.NET, it wrote on my Web
    page an error message of about 10 lines and named
    two 'assemblies' or some such in some temporary
    files somewhere deep on my boot partition.


    Wednesday, November 28, 2012 1:33 AM