BinaryFormatter
is a type-based serialized; it deeply embeds type metadata into the output. I would wager that you have copied the class definition between the projects - that isn't enough for BinaryFormatter
, since that is no longer the same Type
(types are bound to their assembly).
In your scenario, it sounds to me that the correct thing to do here would be to use a contract-based serializer; for example:
- xml (
XmlSerializer
, DataContractSerializer
, etc)
- json (
JavascriptSerializer
, JSON.net, etc)
- binary (protobuf-net, etc)
There would would entirely in your scenario, and would also have much better version tolerance (BinaryFormatter
is very brittle with versions)
You mention "XMLs aren't safe here, as I don't want the users to know the contents of the main database file." - in that case protobuf-net has the "advantage" of being not human-readable, but note: none of these, nor BinaryFormatter
are encrypted; if I wanted to, I could obtain the contents if I really, really wanted to. If you need strong security, use proper encryption. In which case your code becomes (in addition to maybe a few marker attributes):
using(var stream = new FileStream("BinarySerialization.bin", FileMode.Create,
FileAccess.Write, FileShare.None))
{
Serializer.Serialize(stream, words);
}
Edit to show (per comments) how to serialize Dictionary<string, List<Word>>
where Word
is a class with 2 string members (most of the code here is just plumbing to show a complete example):
using System;
using System.Collections.Generic;
using System.IO;
using ProtoBuf;
[ProtoContract]
public class Word {
[ProtoMember(1)]
public string Foo { get; set; }
[ProtoMember(2)]
public string Bar { get; set; }
}
static class Program {
public static void Main() {
var data = new Dictionary<string, List<Word>>{
{"abc", new List<Word> {
new Word { Foo = "def", Bar = "ghi"},
new Word { Foo = "jkl", Bar = "mno"}
}},
{"pqr", new List<Word> {
new Word {Foo = "stu", Bar = "vwx"}
}}
};
using(var file = File.Create("my.bin")) {
Serializer.Serialize(file, data);
}
Dictionary<string, List<Word>> clone;
using(var file = File.OpenRead("my.bin")) {
clone = Serializer.Deserialize<
Dictionary<string, List<Word>>>(file);
}
foreach(var pair in clone) {
Console.WriteLine(pair.Key);
foreach(var word in pair.Value){
Console.WriteLine("\t{0} | {1}", word.Foo, word.Bar);
}
}
}
}