In this article, we will learn about what data contract and known type are in WCF. We will also see their usage and how to mention them.
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,
- Service Contract
- Operation Contract
- Data Contract
- 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 such as, "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 can do this work.
This time, again one question may arise; that is, why we need to mention it? The Data Contract Serializer class serializes all data including private data. For that purpose we mention the DataContract attribute in it. There are two attributes used in the DataContract,
- DataContract Attribute
- DataMember Attribute
The DataContract attribute is used to mention the custom class as data contract and the DataMember attribute is used to mention the data member as a member of the 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 following
article,
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 finished 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 wans to knowif the particular class is child class of a class. It will be declared by the KnownType attribute in the base class of this process, 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 forget 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.
- 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;
- }
- }
- 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);
- }
- 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.
- 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 to comment if you have any questions about it.