Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

protobuf-net Serialize To String and Store in Database Then De Serialize

I'd like to serialize/de-serialize an object using a string. Just to note, when I serialize/de-serialize to a file everything works fine. What I'm trying to do is get a string so I can store it in the database and then pull it out later to de-serialize.

Here is code that works:

MemoryStream msTest = new MemoryStream();
Serializer.Serialize(msTest, registrationBlocks);
msTest.Position = 0;
List<RVRegistrationBlock> CopiedBlocks = new List<RVRegistrationBlock>();
CopiedBlocks = Serializer.Deserialize<List<RVRegistrationBlock>>(msTest);

The "CopiedBlocks" object is the same list that was in "registrationBlocks" Works great, everything serialized/de-serialized. I'm keeping everything in streams here.

Here is the code that doesn't work when I try to get a string involved:

MemoryStream msTestString = new MemoryStream();
Serializer.Serialize(msTestString, registrationBlocks);


msTestString.Position = 0;
StreamReader srRegBlock = new StreamReader(msTestString);

byte[] bytedata64 = System.Text.Encoding.Default.GetBytes(srRegBlock.ReadToEnd());

string stringBase64 = Convert.ToBase64String(bytedata64);

byte[] byteAfter64 = Convert.FromBase64String(stringBase64);
MemoryStream afterStream = new MemoryStream(byteAfter64);


List<RVRegistrationBlock> CopiedBlocksString = new List<RVRegistrationBlock>();
CopiedBlocksString = Serializer.Deserialize<List<RVRegistrationBlock>>(afterStream);

On the last line when it goes to deserialize, I get an exception: Exception of type 'ProtoBuf.ProtoException' was thrown. I can't drill into it, inner exception is null. I can't figure out why it's doing it.

I've definitely narrowed it down to the fact that when I get a string involved it goes haywire. I'm storing the string in a database in an nvarchar(max) which is why I want the string.

Any help would be super appreciated!

like image 715
Robert Avatar asked Aug 01 '11 23:08

Robert


2 Answers

I am little bit lost by the use of the StreamReader in this context, it would seem to me that you could omit that and do something like below to ensure there isn't a one-way encoding happening..

MemoryStream msTestString = new MemoryStream();
Serializer.Serialize(msTestString, registrationBlocks);

string stringBase64 = Convert.ToBase64String(msTestString.ToArray());

byte[] byteAfter64 = Convert.FromBase64String(stringBase64);
MemoryStream afterStream = new MemoryStream(byteAfter64);

List<RVRegistrationBlock> CopiedBlocksString = new List<RVRegistrationBlock>();
CopiedBlocksString = Serializer.Deserialize<List<RVRegistrationBlock>>(afterStream);
like image 66
Quintin Robinson Avatar answered Nov 12 '22 23:11

Quintin Robinson


Based on the answer and the comment, I use these:

        internal static string SerializeToString_PB<T>(this T obj)
        {
            using (MemoryStream ms = new MemoryStream())
            {
                ProtoBuf.Serializer.Serialize(ms, obj);
                return Convert.ToBase64String(ms.GetBuffer(), 0, (int)ms.Length);
            }
        }
        internal static T DeserializeFromString_PB<T>(this string txt)
        {
            byte[] arr = Convert.FromBase64String(txt);
            using (MemoryStream ms = new MemoryStream(arr))
                return ProtoBuf.Serializer.Deserialize<T>(ms);
        }
like image 35
Koray Avatar answered Nov 13 '22 00:11

Koray