C#.Net - A Deserialization problem! Help!!!
-
I have two projects. One is Server and the other is client. I am using udpclient sockets for network communication. To send custom objects I have to serialize and desterilize by using binary formatters and memory streams. It works great if I use a single project having two threads and communicating with each other. But my actual task is to have two separate programs running on any two machines of a network. Now both the programs have different things to do as one is a server and the other is a client. The server waits for the client to send a custom object. The client serializes a custom object into stream of bytes and sends it to the server. At server side, the server receives the incoming stream and has to desterilize it back into the actual custom object. My custom object is completely serializable as described inn msdn. Attribute is there and ISerializable interface is implemented. Both the projects have different names and versions as they are separate assemblies. Now for casting I have included the class of my custom object in both the projects. But, I get an exception at deserialization time in server. The exception is; "An unhandled exception of type 'System.Runtime.Serialization.SerializationException' occurred in mscorlib.dll Additional information: Cannot find the assembly Client.exe Version=1.0.2365, Culture=neutral, PublicKeyToken=null." What I perceive from this exception is that after serializing, the serialized object also contains the Assembly Meta Data info in which it was created e.g. Assembly Name, Assembly Version etc. So, at server side, when the object is deserialized back to its actual state then the CLR finds out that the deserialized object does not have correct information for the current running Assembly which is Server.exe. So, then CLR thinks that this deserialized object is incompatible with the current assembly i.e server.exe and tries to find the assembly Client.exe. When it is unable to find client.exe as it is not at server side so it raises the exception. I solution to this problem is that Client and server programs reside in the same directory, which is never going to happen in my case. Another solution to this problem is that I make a separate .dll for all my custom objects that need to be communicated between server/client and place the same copy of that dll at both the sides. But I don’t want to follow this solution coz then I would be spending my time in just checking the consistency of dll at both sides and what if a dll at some side is mi
-
I have two projects. One is Server and the other is client. I am using udpclient sockets for network communication. To send custom objects I have to serialize and desterilize by using binary formatters and memory streams. It works great if I use a single project having two threads and communicating with each other. But my actual task is to have two separate programs running on any two machines of a network. Now both the programs have different things to do as one is a server and the other is a client. The server waits for the client to send a custom object. The client serializes a custom object into stream of bytes and sends it to the server. At server side, the server receives the incoming stream and has to desterilize it back into the actual custom object. My custom object is completely serializable as described inn msdn. Attribute is there and ISerializable interface is implemented. Both the projects have different names and versions as they are separate assemblies. Now for casting I have included the class of my custom object in both the projects. But, I get an exception at deserialization time in server. The exception is; "An unhandled exception of type 'System.Runtime.Serialization.SerializationException' occurred in mscorlib.dll Additional information: Cannot find the assembly Client.exe Version=1.0.2365, Culture=neutral, PublicKeyToken=null." What I perceive from this exception is that after serializing, the serialized object also contains the Assembly Meta Data info in which it was created e.g. Assembly Name, Assembly Version etc. So, at server side, when the object is deserialized back to its actual state then the CLR finds out that the deserialized object does not have correct information for the current running Assembly which is Server.exe. So, then CLR thinks that this deserialized object is incompatible with the current assembly i.e server.exe and tries to find the assembly Client.exe. When it is unable to find client.exe as it is not at server side so it raises the exception. I solution to this problem is that Client and server programs reside in the same directory, which is never going to happen in my case. Another solution to this problem is that I make a separate .dll for all my custom objects that need to be communicated between server/client and place the same copy of that dll at both the sides. But I don’t want to follow this solution coz then I would be spending my time in just checking the consistency of dll at both sides and what if a dll at some side is mi
my guess would be that this is caused by having events in your object. If anything is hooked up to the event by the client then there would be a refernce to the app in the serialized object. the following code worked for me a while back when i had a similar problem: [field:NonSerialized()] public event EventHandler thisEvent; [field:NonSerialized()] public event EventHandler thatEvent; hope this helps Russ
-
I have two projects. One is Server and the other is client. I am using udpclient sockets for network communication. To send custom objects I have to serialize and desterilize by using binary formatters and memory streams. It works great if I use a single project having two threads and communicating with each other. But my actual task is to have two separate programs running on any two machines of a network. Now both the programs have different things to do as one is a server and the other is a client. The server waits for the client to send a custom object. The client serializes a custom object into stream of bytes and sends it to the server. At server side, the server receives the incoming stream and has to desterilize it back into the actual custom object. My custom object is completely serializable as described inn msdn. Attribute is there and ISerializable interface is implemented. Both the projects have different names and versions as they are separate assemblies. Now for casting I have included the class of my custom object in both the projects. But, I get an exception at deserialization time in server. The exception is; "An unhandled exception of type 'System.Runtime.Serialization.SerializationException' occurred in mscorlib.dll Additional information: Cannot find the assembly Client.exe Version=1.0.2365, Culture=neutral, PublicKeyToken=null." What I perceive from this exception is that after serializing, the serialized object also contains the Assembly Meta Data info in which it was created e.g. Assembly Name, Assembly Version etc. So, at server side, when the object is deserialized back to its actual state then the CLR finds out that the deserialized object does not have correct information for the current running Assembly which is Server.exe. So, then CLR thinks that this deserialized object is incompatible with the current assembly i.e server.exe and tries to find the assembly Client.exe. When it is unable to find client.exe as it is not at server side so it raises the exception. I solution to this problem is that Client and server programs reside in the same directory, which is never going to happen in my case. Another solution to this problem is that I make a separate .dll for all my custom objects that need to be communicated between server/client and place the same copy of that dll at both the sides. But I don’t want to follow this solution coz then I would be spending my time in just checking the consistency of dll at both sides and what if a dll at some side is mi
Hiya, This sounds like the server is expecting to deserialise an object it thinks is in the assembly 'Client.exe'. (due to the containing assembly information being serialised too, and .NET considering the server object and client object to be different things). Ultimately, if your application exists in two parts and you are sharing serialised objects between the two, there needs to be some class reuse here. It seems to me that you can either get this reuse by combining the source file in both assemblies, or build an intermediate assembly as you say. I would argue that the latter is the correct way to go. If the objects reside in a third assembly then you can use assembly versioning to ensure that both client and server are singing from the same songsheet; you don't get this by sharing the source. By sharing the source it also means that if you change the server you would need to recompile the client. Sharing the source also creates a grubbier solution. True, if someone tampers with your dll then you're stuck - but this is the case for all assemblies. I think the consistency check you mention would in effect be done by .NET for you. Just an opinion.... Regards, Rob Philpott.
-
I have two projects. One is Server and the other is client. I am using udpclient sockets for network communication. To send custom objects I have to serialize and desterilize by using binary formatters and memory streams. It works great if I use a single project having two threads and communicating with each other. But my actual task is to have two separate programs running on any two machines of a network. Now both the programs have different things to do as one is a server and the other is a client. The server waits for the client to send a custom object. The client serializes a custom object into stream of bytes and sends it to the server. At server side, the server receives the incoming stream and has to desterilize it back into the actual custom object. My custom object is completely serializable as described inn msdn. Attribute is there and ISerializable interface is implemented. Both the projects have different names and versions as they are separate assemblies. Now for casting I have included the class of my custom object in both the projects. But, I get an exception at deserialization time in server. The exception is; "An unhandled exception of type 'System.Runtime.Serialization.SerializationException' occurred in mscorlib.dll Additional information: Cannot find the assembly Client.exe Version=1.0.2365, Culture=neutral, PublicKeyToken=null." What I perceive from this exception is that after serializing, the serialized object also contains the Assembly Meta Data info in which it was created e.g. Assembly Name, Assembly Version etc. So, at server side, when the object is deserialized back to its actual state then the CLR finds out that the deserialized object does not have correct information for the current running Assembly which is Server.exe. So, then CLR thinks that this deserialized object is incompatible with the current assembly i.e server.exe and tries to find the assembly Client.exe. When it is unable to find client.exe as it is not at server side so it raises the exception. I solution to this problem is that Client and server programs reside in the same directory, which is never going to happen in my case. Another solution to this problem is that I make a separate .dll for all my custom objects that need to be communicated between server/client and place the same copy of that dll at both the sides. But I don’t want to follow this solution coz then I would be spending my time in just checking the consistency of dll at both sides and what if a dll at some side is mi
luckykhalid wrote:
Another solution to this problem is that I make a separate .dll for all my custom objects that need to be communicated between server/client and place the same copy of that dll at both the sides.
This is exactly the "typical" solution. BTW, take a look at what the BinaryFormatter is producing. It's slow, and it's a hog. As someone else posted to a question I was asking, a "bool" (one byte) takes 256 bytes when BinaryFormat'ted. If you can at all avoid the BinaryFormatter, do so. It's intended for reflection deserialization, thus it retains type and version information, which is why you are getting your problem. If you are simply serializing native types, like ints, strings, etc., I would suggest writing your own serialization. I have RawSerializer class that I've written, that will eventually become an article. If you're interested, send me an email and I'll send you the code. It also handles structs like Guid, DateTime, and your own structs, as long as the contents are native types. Marc VS2005 Tips & Tricks -- contributions welcome!
-
my guess would be that this is caused by having events in your object. If anything is hooked up to the event by the client then there would be a refernce to the app in the serialized object. the following code worked for me a while back when i had a similar problem: [field:NonSerialized()] public event EventHandler thisEvent; [field:NonSerialized()] public event EventHandler thatEvent; hope this helps Russ
Well, Russ, I dont have any events in my custom objects. They contain data members only. Thanx for your reply. Regards Khalid
-
Well, Russ, I dont have any events in my custom objects. They contain data members only. Thanx for your reply. Regards Khalid
i just reread your OP, it sounds like you've got a copy of the class referenced, not the same class. If you put the class in a dll which you ship to the client and the server then this should work. The code will owly have matching versions if it is the same dll on both client and server hth Russ