Search code examples
c#wcfknown-types

KnownType Exception with WCF


I have following Service Interface

[ServiceContract]
public interface ICacheService
{
    [OperationContract]
    IEnumerable<CacheResponse> GetCache(IEnumerable<CacheRequest> requests);
}

[DataContract]
[KnownType(typeof(CacheItem))]
[KnownType(typeof(TreeItem))]
[KnownType(typeof(TreeTopGroup))]
[KnownType(typeof(TreeGroup))]
[KnownType(typeof(TreeView))]
[KnownType(typeof(ITreeItem))]
public class CacheResponse
{
    [DataMember]
    public IDictionary<string, CacheItem> CacheItems { get; set; }
    [DataMember]
    public IEnumerable<KCSLuceneDocument> LuceneDocuments { get; set; }
}

The request works so i won't post it. The Response only contains a DateTime, a String and a List of TreeItem. Important part of the TreeItem Class

public class TreeItem : ITreeItem 
{
    public ITreeItem Parent { get; set; }
    .
    . more stuff

}

As soon as the parent Property is set to something other then null, the client gets a System.ServiceModel.Dispatcher.NetDispatcherFaultException.

Stating that the elment \"http://schemas.datacontract.org/2004/07/Core.Base:_x003C_Parent_x003E_k__BackingField\" contains Data of the Type \"http://schemas.datacontract.org/2004/07/Core.Base:TreeItem\" and that the deserializere doesn't know any Type with that name.

I tried using the KnownType Attribute as well as the ServiceKnownType Attribute. Both didn't help. The only thing that worked is changing the type of Parent to TreeItem which i really don't want to do. Especially as it can contain ITreeItems in some other Locations which most likely also break the Service.

Any idea how to solve the problem?


Solution

  • Do you have the [DataContract] attribute on TreeItem? That would be required. if the TreeItem does have a [DataContract] attribute set, I have a few other ideas, but it may require a bit more of the code to be posted. So give it a try and let me know if I can be of more help.

    A hint as to what the other issues may be can be found on the MSDN for Data Contract Known Type.

    The KnownType is needed when the class marked with the Data Contract attribute meets one of the following:

    • The sent data contract is derived from the expected data contract. For more information, see the section about inheritance in Data Contract Equivalence). In that case, the transmitted data does not have the same data contract as expected by the receiving endpoint.
    • The declared type for the information to be transmitted is an interface, as opposed to a class, structure, or enumeration. Therefore, it cannot be known in advance which type that implements the interface is actually sent and therefore, the receiving endpoint cannot determine in advance the data contract for the transmitted data.
    • The declared type for the information to be transmitted is Object. Because every type inherits from Object, and it cannot be known in advance which type is actually sent, the receiving endpoint cannot determine in advance the data contract for the transmitted data. This is a special case of the first item: Every data contract derives from the default, a blank data contract that is generated for Object.
    • Some types, which include .NET Framework types, have members that are in one of the preceding three categories. For example, Hashtable uses Object to store the actual objects in the hash table. When serializing these types, the receiving side cannot determine in advance the data contract for these members.

    source

    If it is marked with [DataContract] you will likely need to add a [ServiceKnownType] attribute on the TreeItem class itself to show possibilities for the TreeItem.Parent property. That is just a conjecture, I would need to see a bit more code first.