We are currently converting our project from .NET Remoting to WCF as the preferred method of remote service calls. One issue we ran into is that some methods worked perfectly while others bombed with a CommunicationException with very little useful information in it. There seemed to be no rhyme or reason as to why some methods worked, but others failed. The exception we always got back on the consumer after trying to make the service call was:
The socket connection was aborted. This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue. Local socket timeout was '00:00:59.2350000'.
The various levels of nested inner exceptions (the innermost being "An existing connection was forcibly closed by the remote host") were no more helpful. Further debugging showed that the call did make it from the consumer to the service and that the service did successfully execute the method in under a second and return the results, so we definitely weren't running into a socket timeout. After turning on the trace writers for WCF and digging through the event output, we saw issues where some of the types we were returning were unrecognized, despite being decorated with [DataContract] attributes:
Type '(type name)' with data contract name '(contract name)' is not expected. Add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.
In our scenario, the culprit ended up being abstract classes our objects inherited. When an object is passed over the wire using WCF, it is instantiated and rehydrated on the other side. If the type is being passed as an abstract, the consuming end does not know what concrete type it should reconstitute the abstract type as. To work around this, you can decorate the abstract class with the [KnownType] attribute, specifying what known concrete types it could be. Why WCF doesn't automatically infer this based on both types being [DataContract]'d, I'm not sure.
For example, if concrete type Person inherits abstract type NamedItemBase and you attempt to call WCF service method "List<NamedItemBase>