Been trying to deserialize a legacy binary file by reconstructing the data structures.
Code was pretty standard, no special cases. I thought I was done but I still kept receiving this error
The ObjectManager found an invalid number of fixups. This usually indicates a problem in the Formatter
Relevant info:
I was working in a submodule with its own assembly
Namespaces were complete and coherent
Same versions of .Net being used
After a very long investigation I attempted to save the binary result of the decompression before proceeding with the deserialization.
I have noticed that although all namespaces were coherent, the original data structure was being hosted within the regular Unity assembly (Assembly-CSharp), while my target data structure was being hosted within a submodule with its own assembly.
Just be mindful of the fact that when serializing/deserializing assembly information is carried over!
Related
I'm serializing some data like fields and custom class to create a binary data (byte array).
Then I want to Deserialize it back from binary data to fields and class.
But I get an exception. It would all work fine if these two methods would happen in same assembly - but its not.
I do Serialization in one assambly, and do the Deserialization in another one. And this is the excaption saying too:
Unable to find assembly 'MyAssamblyName, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.
NOTE 1: I have no issues with getting the fields back, only the classes causes them.
NOTE 2: I have this same class in both assemblies.
NOTE 2: I have this same class in both assemblies
No you don't. At least, not as far as the runtime is concerned. You have two different types that happen to have the same name. A type is defined by its assembly. Thus "SomeType in AssemblyA" is completely different to "SomeType in AssemblyB", even if they happen to have been compiled from the same source file.
BinaryFormatter works with type information, so this won't work. One option would be to move the type to a library dll that both the other projects reference - then it is only defined once, and it will be happy.
Another option is to work with a contract-based serializer (rather than a type-based serializer). This means that "classes that look similar enough" are fine, even if they are in different assemblies (and perhaps have different source, as long as it is "similar enough"). Examples of suitable serializers for this would include (plus a few others) XmlSerializer, DataContractSerializer (but not NetDataContractSerializer), JavaScriptSerializer, or protobuf-net if you want dense raw binary.
All the assemblies containing classes in the class hierarchy of the object you are deserializing must be present in the application in which you are performing this deserialization. They could be either explicitly referenced (if you need compile-time safety with those classes) or only placed in the bin folder of the application so that they could be resolved at runtime. If they are not explicitly referenced you will have to use reflection in order to read the values from the deserialized instance.
I am building a multi-language MVC application and have a series of resource files with translated strings for messages that will be displayed to the user.
Is there any way of ensuring that any resource files added in the future have all required keys and are spelled correctly?
As an analogy, if the resource file was a regular class, you could provide an interface to ensure that all required method and properties were present in the implementing class. Is there a similar concept for resource files?
I've been unable to find a supported way to enforce an explicit contract upon a .resx file. Since your goal is ultimately to catch implementation errors before they show up at runtime (and compile time checking isn't possible), I recommend falling back to static code analysis. Luckily, .NET makes this trivially easy:
Use the System.Resources.ResXResourceReader class to read the contents of the resx files to be validated.
Implement a test that asserts against all required keys in the "contract" you'd like to enforce on the resx.
Test should run as part of an existing test suite, and failure will warn a developer of the implicit contract before encountering the problem at runtime.
Since your resource files will exist in a known location, you can trivially ensure that the tests run against all resx files in that directory. In this way, you don't even need to update the test when new resource files are added, only if the contract changes.
I've used a similar approach to help with maintenance of stored procedure names kept in (an extensive number of) resx files. Since the resource files are spread across dozens of projects, manual maintenance is tedious and error-prone -- in other words, it doesn't get done. The static code analysis approach has yielded few downsides, and I think it would work well in your case as well.
Landing page for resource files on MSDN
ResXResourceReader on MSDN
System.Resources.ResXResourceReader requires a reference to System.Windows.Forms. It's available on both .NET and Mono.
Background
I have encountered a strange situation in my application that uses a 3rd party component. Quite a few classes in my application implements ISerializable interface to basically persist the object state back and forth. I face compatibility issues during the course of serialization when I serialize my app classes in one version and try to deserialize with a different version of 3rd party component.
Issue
The latest release of the 3rd party component saw some major shuffling w.r.t types and assemblies.
i.e. for ex : Earlier a Type T1 found under the assembly A1. . Post new release, where the assembly A1 has now been split to two different assemblies like for ex: A11 and A12. And the type T1 is now housed in A12
The type T1 on deserialization, is trying to find assembly A1. But now since it has been moved to a different assembly like A12 it is throwing SerializationException stating it is not able to find the Assembly A1.
Things I tried:
1. SerializationBinder:
I used a SerializationBinder class which basically checked the incoming assemblyName and TypeName information and suitably routed to the correct assembly on deserialization.
2. AssemblyResolve event using ResolveEventHandler delegate
Basically i can extract the assembly file name from the assembly’s identity and I can re-route the updated path where my application can find the assembly file using call Assembly.LoadFrom to load the assembly and return the resulting Assembly reference back from the ResolveEventHandler method
Although both of the above approach works to a certain extent. It is quite a task to supply the routing information to the correct assembly for all the types that are marked as serializable in my application. Not to mention this has to be updated again for future releases.
So I'm here to ask for help/suggestions/alternatives
Has anyone here has experienced such a situation ?
How were you able to tackle such an issue ?
If you could be generous to shed some best practices and pitfalls to avoid when using Serialization with 3rd party components
Cheers and thanks in advance
VATSAG
About BinaryFormatter:
What are the deficiencies of the built-in BinaryFormatter based .Net serialization?
Let me briefly explain my architecture before I ask my question. I have a client application that calls out to a web service and passes it a couple of items of data. The web service uses this data to do some lookups and then returns a binary serialized object, by using the BinaryFormatter, as a byte array to the client. The client then deserializes the object and uses it. My problem is I had to rename the assembly that the server uses for the new version. This has caused a problem when deserializing in the client. It is not an option for me to deploy a new client just so the new assembly name can be used so my question is, is there a way I can change the Assembly Name that is being written during serialization. I know how to use SerializationBinders for deserializing but that does not solve my problem as that would require deploying a new client.
I am currently using C# 2.0 for both the win forms application and the web service.
If I were using .NET 4 the solution from Thomas would have been perfect. However, .NET 2.0 does not provide this functionality. Instead I just renamed the dlls back to what they were. I would like to eventually rename the dlls but at this point I have not found a viable solution where I would not have to deploy something to the client as well.
You can recreate an empty assembly with the old name containing just the AssemblyInfo.cs, where you put a type redirect:
[assembly: TypeForwardedTo(typeof(MyClassName))], for every type that is moved to another assembly. Ofc this assembly should reference the new one.
But generally consider not using binary serialization for complex data structures, because it's not friendly to such changes as moving types between assemblies.
We are building application that stores objects to isolated storage using .NET runtime serialization.
Problems occur when we update application by adding some new properties to the classes of objects we are serializing. So we want to do some kind of versioning of the objects in isolated storage so we can check if they are obsolete before they are deserialized.
Any advice and ideas how to do this on best possible way?
What do you think about custom formatter implementing IFormatter interface and can it help instead of vesioning objects?
I wrote about this issue on MS forum more detailed here.
You COULD have a serialization in the serialization. First a wrapper class telling the version, and holding the inner true class.
This however feels a bit bad smelly..
Here are a few options (at in any particular order).
Name the file based on the version
Place the file in a directory based on a version
Create a wrapper object that contains metadata about each serialized object such as the version number.
Add a property to each object that contains the persisting application's version number
If its binary serialization, you could read the bytes directly, and determine the assembly version from this. Byte number 22 onwards contains information on the assembly and object type, so you could write something that would read this, and then determine if your objects are obsolete.
Marc Gravell was propose in comment great idea to use version-tolerant serializer.
It enables enough control of deserialization for us even to make obsolete objects reusable.
More on msdn
Thanks to all for suggestions.