From: tutiplain on 4 Sep 2009 13:01 Hi all, This is my first post on this forum. I really hope someone on here can help me, I've been trying to fix this for over a month now, with no success, and posts on Microsoft forums have gone unanswered. I am trying to serialize a generic object (which is marked as serializable, of course) to a Base64 string, writing this string to xml, then reading back the base64 string and deserializing. However, when I deserialize, I get this error Message: Binary stream '0' does not contain a valid BinaryHeader. Possible causes are invalid stream or object version change between serialization and deserialization. I have crosschecked the written values before and after writing them as base64 and they were the same. Here is my code: Public Function Base64EncodeObject(ByVal obj As Object) As String Dim EncodedObject As String Dim unienc As New System.Text.UnicodeEncoding() EncodedObject = "" 'Serialize into byte buffer Dim ser As New System.Runtime.Serialization.Formatters.Binary. BinaryFormatter() Dim ms As New System.IO.MemoryStream() ser.Serialize(ms, obj) ms.Seek(0, IO.SeekOrigin.Begin) Dim buffer(ms.Length) As Byte ms.Read(buffer, 0, ms.Length - 1) bar = buffer EncodedObject = System.Convert.ToBase64String(buffer, Base64FormattingOptions.None) ms.Close() Return EncodedObject End Function Public Function Base64DecodeObject(ByVal EncodedObject As String) As Object Dim UnserializedObject As Object Dim ser As New System.Runtime.Serialization.Formatters.Binary. BinaryFormatter Dim buffer As Byte() buffer = System.Convert.FromBase64String(EncodedObject) Dim ms As New System.IO.MemoryStream(buffer, True) Dim buffer2(buffer.Length - 1) As Byte Dim index As Integer index = 0 While index <= buffer.Length - 1 buffer2(index) = ms.ReadByte index = index + 1 End While Dim ms2 As New System.IO.MemoryStream(buffer2, False) ms2.Position = 0 UnserializedObject = ser.Deserialize(ms2) ms.Close() Return UnserializedObject End Function Any information will be greatly appreciated.
From: Armin Zingler on 4 Sep 2009 13:43 First, you should switch Option Strict On. See inline... > Public Function Base64EncodeObject(ByVal obj As Object) As String .... > Dim buffer(ms.Length) As Byte Dim buffer(CInt(ms.Length) - 1) As Byte 'minus one > ms.Read(buffer, 0, ms.Length - 1) ms.Read(buffer, 0, ms.Length) > Public Function Base64DecodeObject(ByVal EncodedObject As String) As > Object > Dim UnserializedObject As Object > Dim ser As New System.Runtime.Serialization.Formatters.Binary. > BinaryFormatter > > Dim buffer As Byte() > buffer = System.Convert.FromBase64String(EncodedObject) > Dim ms As New System.IO.MemoryStream(buffer, True) > Dim buffer2(buffer.Length - 1) As Byte > > Dim index As Integer > index = 0 > While index <= buffer.Length - 1 > buffer2(index) = ms.ReadByte > index = index + 1 > End While > > Dim ms2 As New System.IO.MemoryStream(buffer2, False) > ms2.Position = 0 > UnserializedObject = ser.Deserialize(ms2) > ms.Close() > Return UnserializedObject > End Function Data flow: string -> buffer -> memorystream -> buffer2 -> memorystream -> object Do I see this right? Why not string -> buffer -> memorystream -> object ? This works, too: Public Shared Function Base64DecodeObject( _ ByVal EncodedObject As String) As Object Dim ser As New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter Dim buffer As Byte() buffer = System.Convert.FromBase64String(EncodedObject) Using ms As New System.IO.MemoryStream(buffer) Return ser.Deserialize(ms) End Using End Function Armin
From: tutiplain on 4 Sep 2009 14:33 Hi, thanks for your reply > Dim buffer(CInt(ms.Length) - 1) As Byte 'minus one I cannot do this, as the MemoryStream object is not initialized until later, based on the size of the buffer. >string -> buffer -> memorystream -> buffer2 -> memorystream -> object Yes, I did it this way to ensure that the data really was inside the buffer. Obviously, it was. Obviously, it also generated the same error. >This works, too: > > Public Shared Function Base64DecodeObject( _ > ByVal EncodedObject As String) As Object > Dim ser As New >System.Runtime.Serialization.Formatters.Binary.BinaryFormatter > > Dim buffer As Byte() > buffer = System.Convert.FromBase64String(EncodedObject) > Using ms As New System.IO.MemoryStream(buffer) > Return ser.Deserialize(ms) > End Using > > End Function > I tried this too, but got the same error message. I have read that this might have to do with incompatible versions of the .net framework, but it can't be as I am running the application on the same computer. Please, any additional suggestions are welcome.
From: Armin Zingler on 4 Sep 2009 15:21 tutiplain schrieb: > Hi, thanks for your reply > >> Dim buffer(CInt(ms.Length) - 1) As Byte 'minus one > > I cannot do this, as the MemoryStream object is not initialized until later, > based on the size of the buffer. I'm afraid, I don't understand what you mean. If you want to copy the whole memory stream with no additional byte into the byte array, the upper bound of the array must be the length of the stream minus one. I tried it with your code and got the same exception. With mine it works. The problem is that EncodedObject = System.Convert.ToBase64String(buffer, Base64FormattingOptions.None) converts the whole buffer. If there is one byte too much, the output string is wrong. Armin
From: tutiplain on 4 Sep 2009 18:38 Hi again, I changed my code to the following, following your suggestion about using only one byte array: Public Function Base64DecodeObject3(ByVal EncodedObject As String) As Object Dim UnserializedObject As Object Dim ser As New System.Runtime.Serialization.Formatters.Binary. BinaryFormatter Dim buffer As Byte() buffer = System.Convert.FromBase64String(EncodedObject) Dim ms As New System.IO.MemoryStream(buffer, True) ms.Position = 0 ms.Flush() UnserializedObject = ser.Deserialize(ms) ms.Close() Return UnserializedObject End Function As you can see, I declare the byte array before the MemoryStream object. I then declare ms using the buffer. This creates a stream that is the same size of the array, with the bytes in it. Therefore, I cannot do what you suggested about declaring the array as Dim buffer(CInt(ms.Length) - 1) As Byte, although their might be a way around this. I also tried out your code: Public Shared Function Base64DecodeObject(ByVal EncodedObject As String) As Object Dim ser As New System.Runtime.Serialization.Formatters.Binary. BinaryFormatter() Dim buffer As Byte() buffer = System.Convert.FromBase64String(EncodedObject) Using ms As New System.IO.MemoryStream(buffer) Return ser.Deserialize(ms) End Using End Function It still threw the Exception. Am I missing something? Could we be using different .net versions (my project is currently set to compile for .net 3.5)? I am using VB 2008 Express. Could I be missing a service pack? I also tried my original code on two different computers, so it's probably not an .net installation issue either. Thanks again for your help and quick replies. Armin Zingler wrote: >tutiplain schrieb: >> Hi, thanks for your reply >> >>> Dim buffer(CInt(ms.Length) - 1) As Byte 'minus one >> >> I cannot do this, as the MemoryStream object is not initialized until later, >> based on the size of the buffer. > >I'm afraid, I don't understand what you mean. If you want to copy the >whole memory stream with no additional byte into the byte array, the >upper bound of the array must be the length of the stream minus one. > >I tried it with your code and got the same exception. With mine it works. > >The problem is that > > EncodedObject = System.Convert.ToBase64String(buffer, >Base64FormattingOptions.None) > >converts the whole buffer. If there is one byte too much, the output >string is wrong. > >Armin
|
Next
|
Last
Pages: 1 2 3 Prev: filling datagridview with excel file data Next: Entity, problem with entity key |