36

I want to make a binary serialize of an object and the result to save it in a database.

Person person = new Person();
person.Name = "something";

MemoryStream memorystream = new MemoryStream();
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(memorystream, person);

How can I transform memorystream in a string type to be saved in database, and after this to be able to deserialize the object?

6 Answers 6

61

What you're really asking for is a safe way of representing arbitrary binary data as text and then converting it back again. The fact that it stores a serialized object is irrelevant.

The answer is almost to use Base 64 (e.g. Convert.ToBase64String and Convert.FromBase64String). Do not use Encoding.UTF8.GetString or anything similar - your binary data is not encoded text data, and shouldn't be treated as such.

However, does your database not have a data type for binary data? Check for BLOB, IMAGE and BINARY types...

Sign up to request clarification or add additional context in comments.

5 Comments

bytes to string --- needs some Encoding.
@loneshark99: I don't understand your comment at all. If this is arbitrary binary data - rather than encoded text - then using an Encoding would be precisely the wrong approach.
I am learning , but I am wondering why Encoding is not the right approach and ToBase64String is.
@loneshark99: Because an Encoding is designed for data that is inherently textual - it converts that text to binary data, whereas base64 and hex are designed for representing inherently binary arbitrary data as text without losing information.
Thanks that makes sense!. I always get confused about encoding. Thank you!!
45

Here's the sample. TData must be marked [Serializable] and all fields type also.

    private static TData DeserializeFromString<TData>(string settings)
    {
        byte[] b = Convert.FromBase64String(settings);
        using (var stream = new MemoryStream(b))
        {
            var formatter = new BinaryFormatter();
            stream.Seek(0, SeekOrigin.Begin);
            return (TData)formatter.Deserialize(stream);
        }
    }

    private static string SerializeToString<TData>(TData settings)
    {
        using (var stream = new MemoryStream())
        {
            var formatter = new BinaryFormatter();
            formatter.Serialize(stream, settings);
            stream.Flush();
            stream.Position = 0;
            return Convert.ToBase64String(stream.ToArray());
        }
    }

Comments

19
//-------write to database-------------------------
Person person = new Person();
person.name = "Firstnm  Lastnm";
MemoryStream memorystream = new MemoryStream(); 
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(memorystream, person);
byte[] yourBytesToDb = memorystream.ToArray();
//here you write yourBytesToDb to database


//----------read from database---------------------
//here you read from database binary data into yourBytesFromDb
MemoryStream memorystreamd = new MemoryStream(yourBytesFromDb);
BinaryFormatter bfd = new BinaryFormatter();
Person deserializedperson = bfd.Deserialize(memorystreamd) as Person;

2 Comments

There should be a using around the MemoryStream
There is a Warning for .Net5.0 and a few other flavors: "The BinaryFormatter type is dangerous and is not recommended for data processing. Applications should stop using BinaryFormatter as soon as possible, even if they believe the data they're processing to be trustworthy. BinaryFormatter is insecure and can't be made secure." learn.microsoft.com/en-us/dotnet/standard/serialization/…
14

I used something like this

MemoryStream memoryStream = new MemoryStream();
BinaryFormatter binaryFormatter = new BinaryFormatter();
binaryFormatter.Serialize(memoryStream, Person);
memoryStream.Flush();
memoryStream.Position = 0;
string value = Convert.ToBase64String(memoryStream.ToArray());

1 Comment

You don't need to rewind a MemoryStream before calling ToArray - it returns the whole stream's data regardless of the current position. Likewise Flush doesn't do anything on a MemoryStream, although it's a good idea for streams in general.
3

Basically, don't save the data as string to the database, there are blob fields available to store binary data.

If you really need to have the data as string, you'll need to convert your byte[] to a string using base64 encoding, and to grab the byte[] from a string use decoding.

Comments

0

Have you not looked into converting the memorystream into a base64hex string to be put into the database?

 byte[] mStream = memorystream.ToArray();
 string sConvertdHex = System.Convert.ToBase64String(mStream)

Then you can dump the contents sConvertdHex to the database. To deserialize it you need to do the reverse

 byte[] mData = System.Convert.FromBase64String(...)

then deserialize mData back to your object.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.