title: Deserializing a MemoryStream - unexpected behaviour
body: <p>At the moment I am experiencing a very frustrating problem. I will try to abstract the problem to make it a bit easier. It has to with serializing my custom object to a database in one process and deserializing it in another process. </p>
  
  <p>I have two assemlies; <code>AppToDB.dll</code> and <code>AppFromDB.dll</code>. I have a 3rd assembly - <code>MyCustomObject.dll</code> - which both of these assemblies contain a reference to. The <code>MyCustomObject.dll</code> extends <code>MarshalByRefObject</code>. </p>
  
  <p>In my <code>AppToDB.dll</code> I execute the following code:</p>
  
  <pre><code>    public bool serializeToDB(MyCustomObject obj)
      {            
          OdbcDataAdapter da = new OdbcDataAdapter();
          MemoryStream memStream = new MemoryStream();
  
          try
          {
              ObjRef marshalledObj = RemotingServices.Marshal((System.MarshalByRefObject)obj);
  
              // Serialize the object; construct the desired formatter
              IFormatter oBFormatter = new BinaryFormatter();
  
              // Try to serialize the object
              oBFormatter.Serialize(memStream, marshalledObj);
  
              // Create byte array
              byte[] serialized = memStream.ToArray();
  
              // Build the query to write to the database
              string queryString = 
                       "INSERT INTO MyCustomObject(id, object) VALUES(?, ?)";
              OdbcCommand command = new OdbcCommand(queryString, connection);
              command.Parameters.AddWithValue("id", 1);
              command.Parameters.AddWithValue("object", serialized);
  
              // Write the object byte array to the database
              int num = command.ExecuteNonQuery();
       }
       catch { }
   }
  </code></pre>
  
  <p>In <code>AppFromDB.dll</code> I execute this code:</p>
  
  <pre><code>    public OCR.Batch deserializeFromDB()
      {            
          MemoryStream memStream = new MemoryStream();
  
          try
          {
              string queryString = "SELECT object FROM FCBatch";
              OdbcCommand command = new OdbcCommand(queryString, connection);
              OdbcDataReader reader = command.ExecuteReader(CommandBehavior.SequentialAccess);
  
              // Size of the BLOB buffer.
              int bufferSize = 100;
              // The BLOB byte[] buffer to be filled by GetBytes.
              byte[] outByte = new byte[bufferSize];
              // The bytes returned from GetBytes.
              long retval;
              // The starting position in the BLOB output.
              long startIndex = 0;
  
              MemoryStream dbStream = new MemoryStream();
  
              while (reader.Read())
              {
                  // Reset the starting byte for the new BLOB.
                  startIndex = 0;
  
                  // Read bytes into outByte[] and retain the number of bytes returned.
                  retval = reader.GetBytes(0, startIndex, outByte, 0, bufferSize);
  
                  // Continue while there are bytes beyond the size of the buffer.
                  while (retval == bufferSize)
                  {
                      dbStream.Write(outByte, 0, bufferSize);
                      dbStream.Flush();
  
                      // Reposition start index to end of last buffer and fill buffer.
                      startIndex += bufferSize;
                      retval = reader.GetBytes(0, startIndex, outByte, 0, bufferSize);
                  }
  
                  // Write the remaining buffer.
                  dbStream.Write(outByte, 0, (int)retval);
                  dbStream.Flush();
              }
              // Close the reader and the connection.
              reader.Close();
  
              dbStream.Position = 0;
              object temp = oBFormatter.Deserialize(dbStream);
              MyCustomObject obj = (MyCustomObject)temp;
  
              return null;
          }
          catch (Exception ex)
          {
              MessageBox.Show(ex.Message);
              return null;
          }
      }
  </code></pre>
  
  <p>OK, so in both pieces of code you can see a <code>MemoryStream</code> object. In the first <code>AppToDB</code> it is created and if I look at its contents it contains 707 bytes. Fine. I write it to the database and save it there as a BLOB. Now in <code>AppFromDB</code> I retrieve the BLOB and store it in a <code>byte[]</code> array. I write the <code>byte[]</code> array to a <code>MemoryStream</code> again, and see that my <code>MemoryStream</code> objects contains 707 bytes, all of which are in place like the original. It seems I have transferred the object with success!</p>
  
  <p>Now the problem lies with <code>object temp = oBFormatter.Deserialize(dbStream);</code>. As soon as I try to deserialize, my <code>object</code> is a Transparent Proxy and I am unable to cast to <code>MyCustomObject</code>!! How do I get my original object back? How in #@&amp;'s name can I have a MemoryStream object....IN memory...ready to be serialized...and suddenly it's a Transparent Proxy again.</p>
  
  <p>I am at loss. Help is appreciated. I will pray to #@&amp; for the one who has the answer ;)</p>
  
  <p><strong>Edit 1</strong>
  OK, I must say things are starting to make sense now (although the problem persists). My problem: I have an object (including state) on one side and I need to store it in the database so I can use it days later by another process on the other side.</p>
  
  <p>My object is not serializable, because it wraps a 3rd party object which is not marked as serializable. So my only option seems to be to marshal, which returns an ObjRef, which in turn IS serializable. But of course - days later - the object I am deserializing is merely the reference and my original object is gone.</p>
  
  <p>How do I solve my problem? More people must have encountered this and I just can't seem to find the answer...</p>
  
  <p><strong>Edit 2</strong>
  OK, I guess I am going to write my own serializable class isomorphic to the 3rd party object. Then run through the whole 3rd party object and, store/wrap its state info etc. Then serialize my object to the database...Seems to be my only option.</p>
  
  <p><strong>Edit 3</strong>
  Starting on this problem again after a while. Just realized though that solution posted in Edit 2 won't work. I have to deserialize into an object the 3rd party assembly knows, since it will continue to perform operations on it.  </p>