views:

318

answers:

2

.NET 2.0 introduced VTS (Version Tolerant Serialization, http://msdn.microsoft.com/en-us/library/ms229752(VS.80).aspx )

A simple test project reveals that the default behavior in 2.0 is to not throw a serialization exception if a field is added to a class, then an attempt is made to deserialize an instance of that class from a binary serialization of a class instance that didn't have the new field.

The default behavior in 1.1 is to throw a serialization exception if a field present in the class is missing in the binary serialized bits.

Besides breaking backwards compatibility (code relying on the exceptions being thrown doesn't work anymore), there's a bigger problem: there is no obvious way to emulate the 1.1 behaviour in 2.0.

How do I emulate the 'throw exception on missing/extra fields' 1.1 behavior in 2.0?

Many thanks, Miron

+1  A: 

In general, people want to be able to at least deserialize old data, regardless of changes to the class design. Unfortunately, BinaryFormatter (being field based) is very brittle here - even switching to automatically implemented properties can break things.

Personally, I would be designing around data-contracts or similar structures that are not implementation specific, and are extensible. For binary, protobuf-net has a lot of uses in this area.

If you really want to emulate the 1.1 behaviour - implement ISerializable by hand and throw the exception (or not) yourself.

Marc Gravell
Thanks, protobuf-net seems an interesting library. I'll consider using it in the future.
Miron Brezuleanu
+2  A: 

Only fields that have the OptionalFieldAttribute attribute applied to them should ignore the missing information during deserialization. Simply removing that attribute should yield an exception, and result in the same behaviour as in .NET Framework 1.1.

Update:

The culprit must be the AssemblyFormat property of the BinaryFormatter class, which is FormatterAssemblyStyle.Full by default in 1.1, but which is FormatterAssemblyStyle.Simple by default in 2.0.

In fact, setting this to FormatterAssemblyStyle.Simple in 1.1 will yield the same behaviour as in 2.0: no exception is thrown. At last in .NET 2.0 you have the OptionalFieldAttribute to be more finegrained.

So set this property to FormatterAssemblyStyle.Full, and see what it does.

See also here.

Dave Van den Eynde
That's what I thought too. But a simple test with a class with a couple of fields (without OptionalFieldAttribute, same code on 1.1 and 2.0) throws a serialization exception on 1.1 and silently uses default values on 2.0.
Miron Brezuleanu
I updated the entry to clarify.
Dave Van den Eynde
Thanks! Setting AssemblyProperty does what I need.
Miron Brezuleanu