Weird BinaryFormatter deseralization error in C# - c#

I am encountering a really weird Exception on one of my application (later referenced as ApplicationB)
`Unable to find assembly 'MsgPack, Version=0.5.0.0, Culture=neutral, PublicKeyToken=a2625990d5dc0167'.`
Here is my scenario, on my ApplicationA I have serialized an object using MsgPack and store it into Redis using SE.Redis. Later on, I query this object and deserialize it (of course still using MsgPack). Once this is done, I am sending this object via a TCP/Componennt that serializes this same object using BinaryFormatter. On the other side, ie on ApplicationB, once the packet arrived, it is deserialized using BinaryFormatter and this is where I get the exception.
I don't have any control on the TCP/Component and the serializer it uses.
So why do I get this error on ApplicationB which should know any thing about MsgPack?
Just a thought I want to share, it seems that MsgPack create on the fly DataContract and when deserializing, it might applies some attributes on the object that conflict with the BinaryFormatter. Of course I am not sure about that.
But has anyone encountered this problem?
Cheers.
EDIT: I noticed that for member of type object, MsgPack adds a lot of members for defining the type store in the object member (like IsDictionary, IsList, etc.). Does it impact BinaryFormatter?

When using binary serialization, only the fully qualified type name and its data is serialized to a byte-array. The serializer on the other side wants to deserialize its data. It first reads the type name from the byte-array and tries to find and instanciate that type. That type must be somewhere in a DLL. So it looks for the given DLL (in your case MsgPack) but it cannot be found. Thus: Make sure the DLL MsgPack is located on both sides.
If it is not possible to to have the DLL on the other side, your could try to serialize the DLL itself and send it over to the other side. First deserialize the DLL, put it inside your bin folder or load it into memory, then deserialize the type with its data. But you must really, really, really make sure if you wanna do that. I wouldn't.
Have you ever considered communicating between AppA en AppB using WCF?

Related

Problem decoding a byte array to an object in C# [duplicate]

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.

Is it possible to generate C# class by deserialization some protocol?

I need to generate or define new class based on deserialization serialized class. So I want to transfer class definition from server to client to have access to it's properties later.
Is it possible and how?
Proper way to do it would be to either expose a schema definition for your service for clients to consume & generate strongly type class definitions from that or provide a DLL with your DTO contract definitions (class/interface definitions) to the client.
If you chose neither of those approaches (no schema & no dll with interfaces) but still
want to generate a class definition, you can in an improper way generate .cs class definitions, from a sample data of the service (call the services couple of times and intercept the responses or use some http client). However this approach does not guarantee that you will get an accurate or/and complete generation. Basically you can go from:
XML->XSD->C# cs class file (or even XML to C# cs file directly)or JSON->C# class file
And deserializing object to dynamic especially when you don't own both the server & client code is pretty much the worst thing you can do. And this way you didn't transfer you class definition to the client. Deserializng to dynamic objects is actually no desrialization at all as matter of fact, it gives you a dictionary of strings with syntactical sugar to access them as properties at runtime with not compile time support which can be equal to a disaster. In short don't do it unless you own all the code (not that it's a good idea then either but maybe you could get by somehow)
One portable way to transfer the property definitions and the data itself is to use the JSON serializer.
You can deserialize into a dynamic object using JSON.Net
Deserialize json object into dynamic object using Json.net

Does .net BinaryFormatter support inheritance?

I currently have a socket application that I use to send string back and forth from a client to a server. I recently decided that it would make more sense to send serialized objects instead but ran into a problem. I converted the code to use the SoapFormatter which allowed me to serialize the objects to string and send the string. I ran into an issue on the client side when trying to deserialize inherited objects. It seems that the soapformatter does not support inheritance. The problem occured during deserialization, if i tried to deserialize the parent object when i send the child object (I dont know if this is correct terminology) it would throw a cast exception.
My question is, does the BinaryFormatter support inheritance??
Both SoapFormatter and BinaryFormatter support serializing objects of types that inherit from other types. In other words, both do support inheritance.
You should probably ask another question about your specific problem with SoapFormatter. Also, just using different formatter most likely won't fix your problem (but you coul've tried it before asking here).

Convert from binary to XML serialization without needing the type

I have a project with a few types that I binary-serialize (BinaryFormatter) to files. I'd now like to create a second project which allows admins to temporarily decode those files into a more readable XML format (e.g., using XmlSerializer).
I could deserialize them into an object of the original type, then reserialize them, but is it at all possible to
skip the deserialization (at least in my own code), and
better yet, not have to reference the type at all in my decoder tool?
If you are referring to .NET's native binary serialization (BinaryFormatter), the problem is that it saves your object (along with all the necessary metadata for deserialization) using an undocumented format (AFAIK).
If you really want to try doing it without deserialization, you can check this article, which appears to have analyzed its format (but the author himself states that it might be incomplete). But my opinion is that it's far too much trouble.
There's no way that you can deserialize to your type without specifying that type, at least with standard XML serialization, however, as long as the object was serialized using xml, you could use one of many XML reader classes to traverse the object without needing to deserialize it. Alternatively, if you happen to be serializing to JSON, there are some libraries out there that will deserialize to anonymous types that you can use.
If the type of conversion you are looking for is purely cosmetic (e.g. to make it more human readable), you could write some RegEx to replace the element tags.

Add new property to a class at runtime using reflection

I have some serialized data (using BinaryFormatter), and wanting to deserialise it. However the deserialise method failed since the current assembly does not have the deleted field. I want to be able to reconstruct earlier assembly at run-time in order to deserialise the data. Appreciated any pointer. Thanks.
the technique is called versiontolerant serialization
see http://msdn.microsoft.com/en-us/library/ms229752.aspx

Categories

Resources