Click here to Skip to main content
15,895,462 members
Articles / Programming Languages / C#
Tip/Trick

What is KnownType Attribute and How to Use It in WCF Technology

Rate me:
Please Sign up or sign in to vote.
4.40/5 (4 votes)
4 Jun 2013CPOL2 min read 79.9K   9   6
What is KnownType attribute and how to use it

Prerequisites

You need to be familiar with the structure of the WCF Technology and C# to better understand.

Introduction

The KnownTypeAttribute class allows you to specify, in advance, the types that should be included for consideration during deserialization.

Normally, when passing parameters and return values between a client and a service, both endpoints share all of the data contracts of the data to be transmitted.

When data arrives at a receiving endpoint, the WCF runtime attempts to deserialize the data into an instance of a common language runtime (CLR) type. The type that is instantiated for deserialization is chosen by first inspecting the incoming message to determine the data contract to which the contents of the message conform. The deserialization engine then attempts to find a CLR type that implements a data contract compatible with the message contents. The set of candidate types that the deserialization engine allows for during this process is referred to as the deserializer's set of "known types."

One way to let the deserialization engine know about a type is by using the KnownTypeAttribute. The attribute cannot be applied to individual data members, only to whole data contract types. The attribute is applied to an outer type that can be a class or a structure. In its most basic usage, applying the attribute specifies a type as a "known type." This causes the known type to be a part of the set of known types whenever an object of the outer type or any object referred to through its members is being deserialized.

Let's Do A Practical Example to Follow

Create a new WCF Service Application and implement the following model:

C#
[DataContract] 
public abstract class Person
	{
		[DataMember]
		public int Code { get; set; }
 
		[DataMember]
		public string Name { get; set; }
	}
[DataContract]  
public class Student : Person
	{
		[DataMember]
		public int StudentId { get; set; }
	}
[DataContract]
public class Teacher : Person
	{
		[DataMember]
		public int TeacherId { get; set; }
	} 

Suppose we want to create a service that can give us lists of all the entities in the system (include Students & Teachers). First, we define the contract in the following way:

C#
[ServiceContract]
    public interface IStudentService
    {
        [OperationContract]
        IEnumerable<Person> GetAll();
    } 

As you can see, the output of GetAll method is Person (Base type of Student & Teacher). So the service we'll implement is in the following form:

C#
public class StudentService : IStudentService
   {
       public IEnumerable<Person> GetAll()
       {
           List<Person> listOfPerson = new List<Person>();
 
           listOfPerson.Add( new Student() 
           { Code = 1, StudentId = 123, Name = "student 1" } );
           listOfPerson.Add( new Student() 
           { Code = 1, StudentId = 124, Name = "student 2"} );
           listOfPerson.Add( new Student() 
           { Code = 1, StudentId = 125, Name = "student 3"} );          
 
 
           listOfPerson.Add( new Teacher() 
           { Code = 2, TeacherId = 321, Name = "Mehran mousavi"} );
           listOfPerson.Add( new Teacher() 
           { Code = 2, TeacherId = 322, Name = "Teacher 2" } );
           listOfPerson.Add( new Teacher() 
           { Code = 2, TeacherId = 323, Name = "Teacher 3"} );
 
           return listOfPerson;
       }

To display the output of this WCF Service, create a new ConsoleApplication project and add this service by AddServiceReference to it.

Main function of our ConsoleApplication project is as follows:

C#
class Program
   {
       static void Main( string[] args )
       {
           StudentService.StudentServiceClient client = 
           		new StudentService.StudentServiceClient();
 
           client.GetAll().ToList().ForEach( _record => 
           {
               Console.Write( "Name : {0}", _record.Name );
               Console.WriteLine( "Code : {0}", _record.Code );
           } );
 
           Console.ReadLine();
       }
   } 

After build and run the ConsoleApplication, we get a error !!!

Image 1

Why !!? The problem is that when you try to invoke the service the actual implementation returns a ChildModel for WCF Deserialize Engine has no knowledge. The clients of the service neither have knowledge of this type.

So you need to explicitly indicate this class that you are using in the implementation but is not part of the contract. This could be done by using the KnownType attribute in base Class of Student & Teacher:

C#
[DataContract]
 [KnownType( typeof( Student ) )]
 [KnownType( typeof(Teacher) )]
 public abstract class Person
 {
     [DataMember]
     public int Code { get; set; }
 
     [DataMember]
     public string Name { get; set; }
 } 

After changing your WCF Service, now you can run Client (ConsoleApplication) and see the result successfully ...

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Iran (Islamic Republic of) Iran (Islamic Republic of)
My name is "Mehran Mousavi", i'am a full time Program Engineer and Web Developer with about 8 years working experience in software development and about 6 years in Web development.

Comments and Discussions

 
QuestionNot Good enough Pin
Member 1347410520-Oct-17 7:05
Member 1347410520-Oct-17 7:05 
Questionabstract in wsdl Pin
HM India15-Sep-14 1:43
professionalHM India15-Sep-14 1:43 
GeneralMy vote of 2 Pin
sank patelkumar23-Feb-14 23:33
sank patelkumar23-Feb-14 23:33 
GeneralOne more thank you Pin
Torsten Tiedt22-Jan-14 4:32
Torsten Tiedt22-Jan-14 4:32 
QuestionThanks Pin
Roshan Ghangare7-Dec-13 8:17
Roshan Ghangare7-Dec-13 8:17 
GeneralThanks Pin
farooge4-Jun-13 12:06
farooge4-Jun-13 12:06 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.