You are using Entity Framework inside your WCF service, and you are returning the entity retrieved from the database. EF dynamically creates a proxy subclass of your class. WCF doesn't know how to handle the proxy subclass.
This article has more detials:
http://msdn.microsoft.com/en-us/library/vstudio/ee705457(v=vs.100).aspx
The POCO proxy type cannot be directly serialized or deserialized by
the Windows Communication Foundation (WCF), because the
DataContractSerializer serialization engine can only serialize and
deserialize known types. The proxy type is not a known type. For more
information, see the Serializing POCO Proxies section in the Working
with POCO Entities topic. To serialize POCO proxies as POCO entities,
use the ProxyDataContractResolver class to map proxy types to POCO
types during serialization.
For some reason MS gives a ProxyDataContractResolver, but not an attribute to apply the resolver. The article describes implementing a ApplyDataContractResolverAttribute and how to apply it to operations.
Update:
There is a related issue with returning EF objects directly through WCF when dealing with circular references. Say class A has a many to one relationship with class B. A has a navigation property to B, and B has a collection of A. This can be handled by marking the DataContract with the attribute [DataContract(IsReference=true)], but if you're passing EF objects back you may not want to add DataContract and DataMember to each class in the model. Instead, The DataContractSerializer can handle this for you by setting the preserveObjectReferences to true. Sowmy Srinivasan has an excellent article describing how to do this: Preserving Object Reference in WCF
Combining the two aproaches of using the ProxyDataContractResolver and the preserveObjectReferences = true, I came up with these classes:
public class ReferencePreservingProxyDataContractSerializerOperationBehavior
: DataContractSerializerOperationBehavior
{
public ReferencePreservingProxyDataContractSerializerOperationBehavior(
OperationDescription operationDescription)
: base(operationDescription) { }
public override XmlObjectSerializer CreateSerializer(
Type type, string name, string ns, IList<Type> knownTypes)
{
return CreateDataContractSerializer(type, name, ns, knownTypes);
}
private static XmlObjectSerializer CreateDataContractSerializer(
Type type, string name, string ns, IList<Type> knownTypes)
{
return CreateDataContractSerializer(type, name, ns, knownTypes);
}
public override XmlObjectSerializer CreateSerializer(
Type type, XmlDictionaryString name, XmlDictionaryString ns,
IList<Type> knownTypes)
{
return new DataContractSerializer(type, name, ns, knownTypes,
0x7FFF /*maxItemsInObjectGraph*/,
false/*ignoreExtensionDataObject*/,
true/*preserveObjectReferences*/,
null/*dataContractSurrogate*/,
new ProxyDataContractResolver());
}
}
public class ReferencePreservingProxyDataContractFormatAttribute : Attribute, IOperationBehavior
{
public void AddBindingParameters(OperationDescription description, BindingParameterCollection parameters)
{
}
public void ApplyClientBehavior(OperationDescription description, System.ServiceModel.Dispatcher.ClientOperation proxy)
{
IOperationBehavior innerBehavior = new ReferencePreservingProxyDataContractSerializerOperationBehavior(description);
innerBehavior.ApplyClientBehavior(description, proxy);
}
public void ApplyDispatchBehavior(OperationDescription description, System.ServiceModel.Dispatcher.DispatchOperation dispatch)
{
IOperationBehavior innerBehavior = new ReferencePreservingProxyDataContractSerializerOperationBehavior(description);
innerBehavior.ApplyDispatchBehavior(description, dispatch);
}
public void Validate(OperationDescription description)
{
}
}
Then for each operation, I just apply [ReferencePreservingProxyDataContractFormatAttribute]