Data Contract And Known Type In WCF

Datetime:2016-08-23 04:36:43          Topic: WCF           Share

In this article, we will go to see about what is data contract and known type in WCF. We will also see its usage and how to mention it. B

Let's start!

What is Contract in WCF

Contract provides the way to know about WCF service and communicate with it. There are four type of contracts available in WCF,
  1. Service Contract
  2. Operation Contract
  3. Data Contract
  4. Message Contract

But in this article, we do not see anything about those contracts except the Data contract.

What is Data Contract

It is used to mention the custom or user defined data type into the WCF service. If you ask question like can’t we achieve it without mentioning the Data contract? The answer will be Yes, you can do it. By default the Data Contract Serializer do this work.

This time, again one question may arise that why we need to mention it. The Data Contract Serializer class serializes all data including private data. That purpose we mention the DataContract attribute in it. There are two attributes used in the DataContract,

  1. DataContract Attribute
  2. DataMember Attribute

The DataContract attribute used to mention the custom class as data contract and the DataMember attribute used to mention the data member as a member of data contract. We can use this for both the data member and properties of the class.

Let us see the steps to create the WCF service and capture it in a client application with data contract.

Step 1:Create one Service library named StudentServiceLib.

Step 2:For creating the DataContract create one class named Student and include the code like this,

[DataContract]  
public class Student  
{  
    [DataMember]  
    public string Name  
    {  
        get;  
        set;  
    }  
    [DataMember]  
    public string Department  
    {  
        get;  
        set;  
    }  
    [DataMember]  
    public int Year;  
}  
Note:

Here, I mention the DataMember attribute for both properties and public member of the class. It’s just for now, we can specify the DataMember attribute.

Step 3:WCF Service in the name StudentService and mention the code like this.

[ServiceContract]  
public interface IStudentService   
{  
    [OperationContract]  
    Student GetStudent(string name);  
  
    [OperationContract]  
    void SaveStudent(Student student);  
}  
  
public class StudentService: IStudentService   
{  
    public Student GetStudent(string name)  
    {  
        switch (name)  
        {  
            case "sakthi":  
                return new Student  
                {  
                    Name = "sakthi", Department = "MCA", Year = 3  
                };  
            case "kumar":  
                return new Student  
                {  
                    Name = "sakthi", Department = "BCA", Year = 3  
                };  
            default:  
                return new Student  
                {  
                    Name = name, Department = "BE", Year = 3  
                };  
        }  
    }  
  
    public void SaveStudent(Student student)  
    {  
  
    }  
}  

If you want to know how to create WCF service, please refer my followingarticle ,

That’s all. Our service is ready to host and implement the following configuration and code to self host the application in a new console application named StudentService.

<system.serviceModel>  
    <services>  
        <service name="StudentServiceLib.StudentService" behaviorConfiguration="mexBehaviour">  
            <endpoint address="StudentService" binding="basicHttpBinding" contract="StudentServiceLib.IStudentService"></endpoint>  
            <host>  
                <baseAddresses>  
                    <add baseAddress="http://localhost:8085" />  
                </baseAddresses>  
            </host>  
        </service>  
    </services>  
    <behaviors>  
        <serviceBehaviors>  
            <behavior name="mexBehaviour">  
                <serviceMetadata httpGetEnabled="true" />  
            </behavior>  
        </serviceBehaviors>  
    </behaviors>  
</system.serviceModel>  
  
ServiceHost host = new ServiceHost(typeof(StudentServiceLib.StudentService)); Console.WriteLine("Try to start the service..."); host.Open(); Console.WriteLine("Service started successfully..."); Console.WriteLine("Press any key to stop the service."); Console.ReadKey();  

Build the solution and run the StudentServer.exe in the administrator mode. If it run successfully the console window will be like the following:

Add the service reference in the client application and implement the code like this to retrieve the student detail.

StudentServiceClient client = new StudentServiceClient();  
Student student = client.GetStudent("sakthi");  
Console.WriteLine("****** Student Detail ******");  
Console.WriteLine("****************************");  
Console.WriteLine("Student Name : " + student.Name);  
Console.WriteLine("Department : " + student.Department);  
Console.WriteLine("Year : " + student.Year);  
Console.ReadKey();  

If we run the application, the output will be like this,

Now, we done the sample application to define the DataContract and run the application. Let us see what is Know type, its usage and how to define it.

What is Known Type

It is nothing but the client want to know the particular class is child class of a class, It will be declared by the KnownType attribute in the base class this process is called known type.

Let us alter the above sample and implement the following code,

[DataContract]  
[KnownType(typeof(HostelStudent))]  
public class Student  
{  
    [DataMember]  
    public string Name   
    {  
        get;  
        set;  
    }  
    [DataMember]  
      
    public string Department  
    {  
        get;  
        set;  
    }  
    [DataMember]  
    public int Year;  
  
}  
  
  
[DataContract]  
public class HostelStudent: Student  
{  
    [DataMember]  
    public string RoomNumber  
    {  
        get;  
        set;  
    }  
}  
  
public class StudentService: IStudentService   
{  
    public Student GetStudent(string name)   
    {  
        switch (name)   
        {  
            case "sakthi":  
                return new HostelStudent   
                {  
                    Name = "sakthi", Department = "MCA", Year = 3, RoomNumber = "A124"  
                };  
            case "kumar":  
                return new Student  
                {  
                    Name = "sakthi", Department = "BCA", Year = 3  
                };  
            default:  
                return new Student  
                {  
                    Name = name, Department = "BE", Year = 3  
                };  
        }  
    }  
  
    public void SaveStudent(Student student)   
    {  
  
    }  
}  

Update the client service reference and change the client code like this,

StudentServiceClient client = new StudentServiceClient();  
HostelStudent student = (HostelStudent) client.GetStudent("sakthi");  
if (student != null)  
{  
    Console.WriteLine("****** Student Detail ******");  
    Console.WriteLine("****************************");  
    Console.WriteLine("Student Name : " + student.Name);  
    Console.WriteLine("Department : " + student.Department);  
    Console.WriteLine("Year : " + student.Year);  
    Console.WriteLine("Hostel Room Number : " + student.RoomNumber);  
}  

Run the application and see the output in the console window.

Suppose if you miss to mention the known type attribute in the base type, it will throw exception.

Ok, let us see what are the ways available to mention the known type in the WCF service. There are four ways available to mention the known type in WCF. 

  1. In the Base type using KnownType attribute,
    [DataContract]  
    [KnownType(typeof(HostelStudent))]  
    public class Student   
    {  
        [DataMember]  
        public string Name  
        {  
            get;  
            set;  
        }  
        [DataMember]  
        public string Department  
        {  
            get;  
            set;  
        }  
        [DataMember]  
        public int Year;  
      
    }  
      
      
    [DataContract]  
    public class HostelStudent: Student  
    {  
        [DataMember]  
        public string RoomNumber  
        {  
            get;  
            set;  
        }  
    }  
    
  2. By mentioning the ServiceKnownType attribute in the service level. Here the Specified type is known type only to this service.
    [ServiceContract]  
    [ServiceKnownType(typeof(HostelStudent))]  
    public interface IStudentService  
    {  
        [OperationContract]  
        Student GetStudent(string name);  
      
        [OperationContract]  
        void SaveStudent(Student student);  
    }  
    
  3. By mention the ServiceKnownType attribute in the operation level. Here the specified type is known type only to that operation.
    [OperationContract]  
    [ServiceKnownType(typeof(HostelStudent))]  
    Student GetStudent(string name);  
    
    If we try to access the Hostel student out of GetStudent operation, it will throw exception.
  4. Mention the following configuration in the web.config or app.config file.
    <system.runtime.serialization>  
        <dataContractSerializer>  
            <declaredTypes>  
                <add type="StudentServiceLib.Student, StudentServiceLib, Version=1.0.0.0, PublicKeyToken=null">  
                    <knownType type="StudentServiceLib.HostelStudent, StudentServiceLib, Version=1.0.0.0, PublicKeyToken=null"></knownType>  
                </add>  
            </declaredTypes>  
        </dataContractSerializer>  
    </system.runtime.serialization>  
    
    It will be available to all services mentioned in the service host.
    That’s all, please feel free if you have any doubt in it.




About List