I have the following C # code that should serialize arbitrary objects into a string, and then, of course, deserialize it.
public static string Pack(Message _message) { BinaryFormatter formatter = new BinaryFormatter(); MemoryStream original = new MemoryStream(); MemoryStream outputStream = new MemoryStream(); formatter.Serialize(original, _message); original.Seek(0, SeekOrigin.Begin); DeflateStream deflateStream = new DeflateStream(outputStream, CompressionMode.Compress); original.CopyTo(deflateStream); byte[] bytearray = outputStream.ToArray(); UTF8Encoding encoder = new UTF8Encoding(); string packed = encoder.GetString(bytearray); return packed; } public static Message Unpack(string _packed_message) { UTF8Encoding encoder = new UTF8Encoding(); byte[] bytearray = encoder.GetBytes(_packed_message); BinaryFormatter formatter = new BinaryFormatter(); MemoryStream input = new MemoryStream(bytearray); MemoryStream decompressed = new MemoryStream(); DeflateStream deflateStream = new DeflateStream(input, CompressionMode.Decompress); deflateStream.CopyTo(decompressed);
But the problem is that at any time when the code runs, I experience an exception. Using the code above and calling it as shown below, I get an InvalidDataException: Unknown block type. The stream may be damaged. on the marked line // EXCEPTION .
After searching for this problem, I tried to thwart deflation. This was only a small change: in Pack , bytearray is created from original.ToArray() and Unpack , I Seek() input instead of decompressed and uses Deserialize(input) instead of decompressed too, the only result that has changed: exception position and body are different, but yet this is happening. I get a SerializationException: no map for object '201326592'. with // EXCEPTION 2 .
I donβt seem to see what the problem is. Perhaps this is the whole idea of ββserialization ... the problem is that somehow managed to collect instances of Message , because these objects contain information that moves between the server and the client application. (The logic of Serialization is in a DLL project with the extension .Shared, which refers to both ends, however, right now, I only develop the server side first.) I also need to say that I use only string tags because right now there is a TCP connection between servers and customers based on reading and writing lines at the ends. So this should be reduced to string level.
Here's what the Message object looks like:
[Serializable] public class Message { public MessageType type; public Client from; public Client to; public string content; }
( Client now an empty class with a Serializable attribute, no properties or methods.)
Here's how the unpack package is called (from Main() ...):
Shared.Message msg = Shared.MessageFactory.Build(Shared.MessageType.DEFAULT, new Shared.Client(), new Shared.Client(), "foobar"); string message1 = Shared.MessageFactory.Pack(msg); Console.WriteLine(message1); Shared.Message mess2 = Shared.MessageFactory.Unpack(message1);
Here is an image showing what is happening in the IDE. The output in the console window is message1 . 
Unfortunately, some studies have also shown that the problem may lie around the bytearray variable. When Pack() run after the encoder creates a string, the array contains 152 values; however, after it is decoded in Unpack() , the array has 160 instead.
I appreciate any help, because I am really out of ideas, and this problem is related to progress. Thanks.
(Update) Final Solution:
I would like to thank everyone who answered and commented on as I reached a solution. Thanks.
Mark Gravell was right, I missed the deflateStream closure, and because of this, the result was either empty or damaged. I spent my time and rethought and rewrote the methods, and now it works flawlessly. And even the goal of sending these bytes over the network stream also works.
Also, as Eric J. suggested, I switched to using ASCIIEnconding to change between string and byte[] when data flows in Stream .
The fixed code is below:
public static string Pack(Message _message) { using (MemoryStream input = new MemoryStream()) { BinaryFormatter bformatter = new BinaryFormatter(); bformatter.Serialize(input, _message); input.Seek(0, SeekOrigin.Begin); using (MemoryStream output = new MemoryStream()) using (DeflateStream deflateStream = new DeflateStream(output, CompressionMode.Compress)) { input.CopyTo(deflateStream); deflateStream.Close(); return Convert.ToBase64String(output.ToArray()); } } } public static Message Unpack(string _packed) { using (MemoryStream input = new MemoryStream(Convert.FromBase64String(_packed))) using (DeflateStream deflateStream = new DeflateStream(input, CompressionMode.Decompress)) using (MemoryStream output = new MemoryStream()) { deflateStream.CopyTo(output); deflateStream.Close(); output.Seek(0, SeekOrigin.Begin); BinaryFormatter bformatter = new BinaryFormatter(); Message message = (Message)bformatter.Deserialize(output); return message; } }
Now everything happens correctly, as shown below. This was the expected result from the first place. The server and client executables interact with each other, and the message moves ... and it becomes serialized and unesterialized.
