WCF KnownType attribute example

In this article I will present an easy to understand example when to use Data Contract Known Types, e.g. the KnownTypeAttribute class, to make a WCF Service serialize and a service consumer deserialize types when using inheritance. The MSDN has the complete documentation on this, take a look here: KnownTypeAttribute Class.

In this example I will use a hierarchy of different types of vehicles, e.g. a base vehicle type, a car type, a bike type and a kid’s bike type. I will use WCF 4 (.NET 4), Visual Studio 2010 and the WcfTestClient to test the service.
The great thing with KnownTypeAttribute is that WCF can expose one method supporting all types in a class in a hierarchy.

Classes to expose

The class hierarchy looks like this:

This is a really simple inheritance model but will still show the concept of using the KnownTypeAttribute class.

Note that the Vehicle class is abstract due to the abstract NoOfWheels property.

The code behind this class diagram looks like this (comments below the code):

using System.Runtime.Serialization;

namespace WcfKnowTypesLab
{
    ///
    /// Base class, abstract
    ///
    [KnownType(typeof(Car))]
    [KnownType(typeof(Bike))]
    abstract public class Vehicle
    {
        public int ID { get; set; }

        abstract public int NoOfWheels { get; }

        public string Brand { get; set; }
    }

    ///
    /// Car class, inherits from Vehicle
    ///
    public class Car : Vehicle
    {
        override public int NoOfWheels { get { return 4; } }

        public string SteeringWheelPosition { get; set; }
    }

    ///
    /// Bike class, inherits from Vehicle
    ///
    [KnownType(typeof(KidsBike))]
    public class Bike : Vehicle
    {
        override public int NoOfWheels { get { return 2; } }

        public bool HasFrontWheelBreak { get; set; }
    }

    ///
    /// Kid's bike class, inherits from Bike
    ///
    public class KidsBike : Bike
    {
        public bool HasSupportingWheels { get; set; }
    }
}

Comments:

  • The DataContract attribute is left out. This will make all public properties implementing both get and set methods to be serialized by WCF.
  • The property NoOfWheels (marked as abstract in the vehicle class) will not be serialized due to the missing set method.
  • The vehicle class has two instances of the KnownType attribute, Car and Bike, that make Car and Bike objects valid as parameter and return value types by WCF.
  • The bike class have a KnownType attribute pointing out the KidsBike class, that makes the KidsBike object valid as parameter and return value type by WCF.

Above the usage of the KnownType attribute is shown. Let’s take a look at the service interface and the implementation. The WcfTestClient is used below to test the service.

The service interface

The service will expose two methods, one returning a Vehicle and one taking a Vehicle as parameter. The interface exposed by the service looks like this:

using System.ServiceModel;

namespace WcfKnowTypesLab
{
    [ServiceContract]
    public interface IVehicleService
    {
        [OperationContract]
        Vehicle GetVehicle(int type);

        [OperationContract]
        int GetNumberOfWheels(Vehicle vehicle);
    }
}

The GetVehicle function need an integer parameter to decide the type of vehicle to return (see the code for the implementation of  the interface below).

The GetNumberOfWheels returns the number of wheels of the vehicle passed as parameter (the number of wheels property will not be serialized since it doesn’t implement any set method, see code below).

The implementation of the interface looks like this:

namespace WcfKnowTypesLab
{
    public class VehicleService : IVehicleService
    {
        public Vehicle GetVehicle(int type)
        {
            switch (type)
            {
                case 0:
                    return new Car()
                    {
                        ID = 10,
                        Brand = "Volvo",
                        SteeringWheelPosition = "left"
                    };

                case 1:
                    return new Bike()
                    {
                        ID = 11,
                        Brand = "Scott",
                        HasFrontWheelBreak = true
                    };

                case 2:
                    return new KidsBike()
                    {
                        ID = 12,
                        Brand = "Kid Scott",
                        HasFrontWheelBreak = false,
                        HasSupportingWheels = true
                    };

                default:
                    return null;
            }
        }

        public int GetNumberOfWheels(Vehicle vehicle)
        {
            return vehicle.NoOfWheels;
        }
    }
}

The to functions above is straight forward, but let’s make a couple of comments anyway:

  • The GetVehicle function will return an object of a certain type, based on the type parameter:
    • 0: A Car object is returned
    • 1: A Bike object is returned
    • 2: A KidsBike object is returned
    • null otherwise
  • The different types of vehicles returned are valid Vehicle type objects and they will be serialized correctly because of the KnownType attribute shown above.
  • The GetNumberOfWheels function will return the number of wheels (more or less constant, depending on the subclass object passed as parameter). Take a closer look at the NumberOfWheels property for the classes shown above.

Service testing

First I will show the results of invoking the GetVehicle function, with all the valid type parameter values.

GetVehicle(0):

GetVehicle(1):

GetVehicle(2):

GetVehicle(<some value causing null to be returned, e.g. 99):

The above screenshots of the WcfTestClient show the different types of objects returned by the service, depending on the type parameter passed to the service function.

Let’s take a look at the GetNumberOfWheels function. I will pass a Car and a KidsBike object as parameters

GetNumberOfWheels(<a Car object>):

GetNumberOfWheels(<a KidsBike object>):

Note that an object of type Vehicle may not be returned or passed as parameter since it is abstract. A subclass needs to implement the abstract stuff in such a class.

These screenshots showing the results from the different functions exposed by the service ends this article. Isn’t the KnownType attribute a nice feature? I like it very much!

Tagged with: , , ,
Posted in .NET, C#, WCF
14 comments on “WCF KnownType attribute example
  1. rh says:

    This was very helpful – thanks for writing this!

  2. Hassan says:

    Hi,

    Thanks for this easy to understand article.
    I am having serialization issue when using inheritance. It seems the properties in the base class never get serialized. I am using DataContract attribute in all of my classes. Is this the reason?
    Following is the code for my base class.

    [WcfSerialization::KnownType(typeof(Candidate))]
    [WcfSerialization::KnownType(typeof(CandidateDocuments))]
    [WcfSerialization::DataContract(Namespace = "http://www.abc.co.uk/it/soaservices/crm", Name = "BaseContract")]
    public partial class BaseContract
    {
    private int id;
    private System.DateTime insertDate;
    private int insertENTUserAccountId;
    private System.DateTime updateDate;
    private int updateENTUserAccountId;
    private string displayText;
    [WcfSerialization::DataMember(Name = "ID", IsRequired = false, Order = 0)]
    public int ID
    {
    get { return id; }
    set { id = value; }
    }

    [WcfSerialization::DataMember(Name = "InsertDate", IsRequired = false, Order = 1)]
    public System.DateTime InsertDate
    {
    get { return insertDate; }
    set { insertDate = value; }
    }

    [WcfSerialization::DataMember(Name = "InsertENTUserAccountId", IsRequired = false, Order = 2)]
    public int InsertENTUserAccountId
    {
    get { return insertENTUserAccountId; }
    set { insertENTUserAccountId = value; }
    }

    [WcfSerialization::DataMember(Name = "UpdateDate", IsRequired = false, Order = 3)]
    public System.DateTime UpdateDate
    {
    get { return updateDate; }
    set { updateDate = value; }
    }

    [WcfSerialization::DataMember(Name = "UpdateENTUserAccountId", IsRequired = false, Order = 4)]
    public int UpdateENTUserAccountId
    {
    get { return updateENTUserAccountId; }
    set { updateENTUserAccountId = value; }
    }

    [WcfSerialization::DataMember(Name = "DisplayText", IsRequired = false, Order = 5)]
    public string DisplayText
    {
    get { return displayText; }
    set { displayText = value; }
    }

  3. Hassan says:

    [WcfSerialization::KnownType(typeof(Candidate))]
    [WcfSerialization::KnownType(typeof(CandidateDocuments))]
    [WcfSerialization::DataContract(Namespace = "http://www.abc.co.uk/it/soaservices/crm", Name = "BaseContract")]
    public partial class BaseContract
    {
    private int id;
    private System.DateTime insertDate;
    private int insertENTUserAccountId;
    private System.DateTime updateDate;
    private int updateENTUserAccountId;
    private string displayText;

    [WcfSerialization::DataMember(Name = "ID", IsRequired = false, Order = 0)]
    public int ID
    {
    get { return id; }
    set { id = value; }
    }

    [WcfSerialization::DataMember(Name = "InsertDate", IsRequired = false, Order = 1)]
    public System.DateTime InsertDate
    {
    get { return insertDate; }
    set { insertDate = value; }
    }

    [WcfSerialization::DataMember(Name = "InsertENTUserAccountId", IsRequired = false, Order = 2)]
    public int InsertENTUserAccountId
    {
    get { return insertENTUserAccountId; }
    set { insertENTUserAccountId = value; }
    }

    [WcfSerialization::DataMember(Name = "UpdateDate", IsRequired = false, Order = 3)]
    public System.DateTime UpdateDate
    {
    get { return updateDate; }
    set { updateDate = value; }
    }

    [WcfSerialization::DataMember(Name = "UpdateENTUserAccountId", IsRequired = false, Order = 4)]
    public int UpdateENTUserAccountId
    {
    get { return updateENTUserAccountId; }
    set { updateENTUserAccountId = value; }
    }

    [WcfSerialization::DataMember(Name = "DisplayText", IsRequired = false, Order = 5)]
    public string DisplayText
    {
    get { return displayText; }
    set { displayText = value; }
    }

  4. Prior to sharing your content to article directory sites release them on your own site. Wait to have them indexed and subsequently do your mass syndication.

  5. This write-up is certainly very informative. I appreciate the effort you spent writing this document. I would like to become a nurse, do you have any thought where I could get details about nurse salaries, job points and what is the basis. Any idea where I could get this info?

  6. Hi there, i read your blog occasionally and i own a similar one and i was just wondering if you get a lot of spam remarks? If so how do you reduce it, any plugin or anything you can advise? I get so much lately it’s driving me insane so any assistance is very much appreciated.

  7. It is truly a great and helpful piece of info. I am happy that you simply shared this useful information with us. Please stay us informed like this. Thank you for sharing.

  8. Have you seen something that the most recent gossip is actually in Sydney? That is definitely so dazzling.

  9. Have you watch the illustrations or photos? You must think about your upcoming holiday getaway to Amsterdam, really it is worthwhile. If you are consistently wondering why the most suitable urban center around the globe is Amsterdam, you should follow the hyperlink. Did you hear the things they improved over there a week ago?

  10. shoeb says:

    hey nice article bro

  11. We absolutely love your blog and find the majority of your post’s to be what precisely I’m looking for.
    Do you offer guest writers to write content for you personally?

    I wouldn’t mind writing a post or elaborating on many of the subjects you write related to here. Again, awesome web log!

  12. goods says:

    I am only commenting to let you know of the fabulous discovery my friend’s daughter undergone viewing your blog. She realized some issues, which included what it’s like to possess a very effective coaching spirit to make the rest effortlessly learn certain extremely tough subject matter. You undoubtedly exceeded my expectations. I appreciate you for imparting such precious, healthy, revealing and in addition unique tips about that topic to Tanya.

  13. Heather says:

    “WCF KnownType attribute example | freddes.
    se” was in fact a beneficial blog post. If solely there was significantly more blogs
    just like this particular one on the world wide web. Regardless, many thanks for ur time, Nikole

  14. mobile games says:

    Terrific work! This is the kind of info that should be shared around
    the internet. Shame on Google for not positioning this publish upper!
    Come on over and consult with my website . Thank you
    =)

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>