Wednesday 12 January 2011

Message: An existing connection was forcibly closed by the remote host

This message tells me that something has gone wrong with the WCF communication between the server and the client.

After narrowing down the code causing the issue, it turns out i was adding an object to a collection and that object was not serializable.

I then created a proxy for that object within the project holding all the other serializable objects.

This was the convention of the application i was working on.

Each proxy object already in the project had three attributes:

[DataContract]
[KnownType]
[Serializable]

Once i gave my proxy objects these attributes and the correct corresponding values (eg the namespace of the DataContract schema) i thought i would be able to add the proxy object to the collection and send it over the wire via the service.

However, i was greeted with the same exception:

An existing connection was forcibly closed by the remote host

Without much clue as to why. So i investigated the differences between my proxy object and the other objects in the project and found two major differences:

1. They were all in the same namespace - within a particular namespace (ApplicationServices.BusinessEntities).
So all i had to do was add my proxy object to be within the correct namespace.

However, i was greeted with another exception:

Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.

2. The final thing was that they all inherited a BaseEntity type.

NOTE: Follow the stack trace for the above exception led me to a KnownTypes method (good naming as it instantly clicked in my mind that of course, there would be a list of all the Types that one can send over the wire and if the Type isn't in that list, then it shouldn't fly!

Inspecting this method revealed that all Classes within a particular namespace (ApplicationServices.BusinessEntities) were being added to the list.

So all i had to do was add my proxy object to be within the correct namespace and it would be added to the KnownTypes list.

But just adding them to the namespace wasn't good enough because the KnownTypes method actually inspected all Dervied Types of BaseEntity AND then made sure that they were in the namespace before adding them to the list.

So in summary:

1. Make sure you only add objects to the collection (which will be sent via WCF) that are serializable and have a proper [DataContract] attribute
2. Make sure that the objects derive from the correct base type and are in the correct namespace in order to be added to the KnownTypes list

Amen.

No comments:

Post a Comment