Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# Deserialize a class which has moved or been renamed

If I have a class named "MyClass" in an assembly named "AssemblyA" and serialize it to a file using .NET's BinaryFormatter. Then move the code of "MyClass" into an assembly named "AssemblyB" and try to deserialize the file I get the following "System.TypeLoadException" exception:

Could not load type 'AssemblyA.MyClass' from assembly 'AssemblyA, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.

Is there any way for me to indicate that the class has been moved to AssemblyB? Via an attribute of some sort? Or is it possible to modify the serialised file as a pre-preprocessing step to change all references from AssemblyA.MyClass to AssemblyB.MyClass? Finally, if neither of those options are possible, is it possible to bypass trying to deserialise this class and continue deserialising the rest of the data anyway?

like image 763
Martin Sherburn Avatar asked Sep 23 '09 10:09

Martin Sherburn


People also ask

What is the full name of C?

In the real sense it has no meaning or full form. It was developed by Dennis Ritchie and Ken Thompson at AT&T bell Lab. First, they used to call it as B language then later they made some improvement into it and renamed it as C and its superscript as C++ which was invented by Dr.

What is C in C language?

What is C? C is a general-purpose programming language created by Dennis Ritchie at the Bell Laboratories in 1972. It is a very popular language, despite being old. C is strongly associated with UNIX, as it was developed to write the UNIX operating system.

Is C language easy?

C is a general-purpose language that most programmers learn before moving on to more complex languages. From Unix and Windows to Tic Tac Toe and Photoshop, several of the most commonly used applications today have been built on C. It is easy to learn because: A simple syntax with only 32 keywords.

What is C language used for?

C programming language is a machine-independent programming language that is mainly used to create many types of applications and operating systems such as Windows, and other complicated programs such as the Oracle database, Git, Python interpreter, and games and is considered a programming foundation in the process of ...


1 Answers

If you have moved it, then add a reference to the dll where it now resides, and use TypeForwardedToAttribute:

[assembly:TypeForwardedTo(typeof(TheType))]

This will be enough for some requests (including BinaryFormatter IIRC) looking for a type to find it in the new assembly. However, IIRC it only works for outermost types (not nested types, and probably not generics), and you can't have renamed it / changed the namespace / etc.

Renaming is tricker... BinaryFormatter is notoriously brittle about such things. IMO, it is only suitable for serializing transient data between two tightly coupled systems (for example, exchange between two AppDomains in the same process; when used for storage, or between systems that might get out of sync, it can be a nightmare.

It may be too late, but I would recommend using a contract-based serializer (rather than a type-based serializer); any of XmlSerializer, DataContractSerializer (as long as you use the [DataContract]/[DataMember] attributes), etc. Of if you want fast binary, protobuf-net would do a good job (and can hook into ISerializable if you need).

Another concept that might be worth looking at is serialization surrogates, but that is relatively hard. But IIRC this gives you the control over the type that is created - but you need to do a lot of the work for it.

like image 56
Marc Gravell Avatar answered Sep 30 '22 23:09

Marc Gravell