While testing a SQL CLR procedure recently I came across an issue with the binary formatter deserialization failing because it could not find the assembly for the type (even though the type is within the same assembly as the deserialization code).
The database application I have been working on has an initial request object (from a web service or web site) that is serialized using the binary formatter and stored in a Request table. It is then added into a Queue to be processed by one or more Service Broker services at a later time.
The serialization and deserialization of the request object is performed by a SQL CLR procedure, utilising the “System.Runtime.Serialization.Formatters.Binary.BinaryFormatter” formatter.
While testing that the Service Broker was configured correctly I was reusing the same Request table data, where the request object had previously been serialized and saved to the table. However I quickly noticed that after re-deploying the SQL CLR project I was running into an error while deserializing the object (note: the type being serialized/deserialized is in the same assembly as the code that serializes it):
Unable to find assembly 'MyAssembly; Version=1.0.3463.18923; Culture=neutral; PublicKeyToken=40e3171cc8066fe6'.
After a little googling it became apparent that the binary formatter stores the type information within the serialized object so that it knows what type to deserialize it to (that makes sense), however this becomes a big issue if you are storing data for periods of time and need to maintain backwards compatibility with new versions of the assembly containing the type information.
Luckily the guys at MS had thought of this and provided us with the “System.Runtime.Serialization.SerializationBinder” class. By inheriting from this class it is possible to redirect all the requests for types from the binary formatter to the types of your choice.
Here is a sample that will allow the types to be found in the current assembly regardless of which version of the assembly originally created the serialized stream:
In my case the type itself had not changed between assembly versions, only the assembly version information. However the MSDN link below shows an example of allowing backwards compatibility between different versions of the type where the type itself may have changed significantly.
P.S. this would also be a great solution if you are attempting to deserialize an object that was created in a different assembly that you cannot reference in your own project for some reason – providing you know the structure of the object and create a similar class in your own assembly.