WCF with Subclasses, Abstract Classes and Interfaces

Building a domain object model will inevitably lead to creating subclasses, abstract classes and interfaces to represent related objects and concepts. Polymorphism is after all a core tenant of object-oriented languages. C# handles these concepts gracefully as they are first class citizens within the language. However, managing these concepts in the world of web services (in this case SOAP) and the need to serialize and deserialize the objects into XML or JSON presents a challenge within the staticly typed nature of C# (ignoring the dynamic features of .net 4.0). Keeping in mind C# is staticly typed, how can a deserialization engine determine the proper type to be created when the only information available is an abstract class or interface? The engine would have to discover the available concrete types inspect the properties of each and figure out which object correctly maps to the serialized object.

[DataContract]
public class MyClass
{
    [DataMember]
    public IEnumerable<IAnimal> Animals { get; set; }
}

public interface IAnimal
{
    string Name { get; set; }
}

[DataContract]
public class Dog : IAnimal
{
    [DataMember]
    public string Name { get; set; }

    [DataMember]
    public bool IsMansBestFriend { get; set; }
}

[DataContract]
public class Cat : IAnimal
{
    [DataMember]
    public string Name { get; set; }
    
    [DataMember]
    public string FavoriteCatFood { get; set; }
}

In fact, WCF won’t even return the DataContract MyClass. WCF can’t figure out how to deserialize the list of dogs and cats. The solution is to use the KnownTypes attribute on the DataContract making use of these subclassed objects. With the KnownType attribute, WCF knows which concrete objects to use when deserializing.

[DataContract]
[KnownType(typeof(Dog))]
[KnownType(typeof(Cat))]
public class MyClass
{
    [DataMember]
    public IEnumerable<IAnimal> Animals { get; set; }
}

It appears WCF handles this situation a bit differently depending on whether you’re using Add Service Reference to go after the WSDL or if you’re using the contracts directly and opening a ChannelFactory. Using the WSDL it appears you’ll get back a list of objects, not strongly typed. If you’re using the ChannelFactory and using the contract definitions then you’ll get strongly typed results.

Advertisements

One thought on “WCF with Subclasses, Abstract Classes and Interfaces

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s