Before reading this article, I highly recommend reading my previous parts:
According to MSDN the KnownTypeAttribute class allows you to specify, in advance, the types that should be included for consideration during deserialization. The WCF service generally accepts and returns the base type. If you expect the service to accept and return an inherited type then we use the knowntype attribute. In other words, by default you cannot use a subclass of the data contract class instead of its base class. We need to tell explicitly to WCF about the subclass using the knowntype attribute. Let me explain with an example.
Create a WCF application and implement the following datacontract.
- using System.Runtime.Serialization;
- using System.ServiceModel;
-
- namespace WcfDemo
- {
- [ServiceContract]
- public interface IBuilder
- {
- [OperationContract]
- Builder GetBuilder();
-
- [OperationContract]
- Builder GetBuilderById(Builder builder);
- }
-
-
- [DataContract]
- public class Builder
- {
- [DataMember]
- public int BuilderId { get; set; }
-
- [DataMember]
- public string BuilderName { get; set; }
-
- [DataMember]
- public string MobileNo { get; set; }
-
- public enum BuilderType { DayBasic = 1, ContractBasis = 2 }
- }
-
- public class DayBasic : Builder
- {
- public int LabourCharges { get; set; }
- public int WorkedDay { get; set; }
- public enum LabourType { Fitter =1, Helper =2}
- }
-
- public class ContractBasis : Builder
- {
- public int TotalAmount { get; set; }
- public int DayComplited { get; set; }
- }
- }
As I said above we can not use a subclass of the data contract class instead of its base class. To do that I will use KnownTypeAttribute.
- using System.Runtime.Serialization;
- using System.ServiceModel;
-
- namespace WcfDemo
- {
- [ServiceContract]
- public interface IBuilder
- {
- [OperationContract]
- Builder GetBuilder();
-
- [OperationContract]
- Builder GetBuilderById(Builder builder);
- }
-
- [KnownType(typeof(DayBasic))]
- [KnownType(typeof(ContractBasis))]
- [DataContract]
- public class Builder
- {
- [DataMember]
- public int BuilderId { get; set; }
-
- [DataMember]
- public string BuilderName { get; set; }
-
- [DataMember]
- public string MobileNo { get; set; }
-
- public enum BuilderType { DayBasic = 1, ContractBasis = 2 }
- }
-
- public class DayBasic : Builder
- {
- public int LabourCharges { get; set; }
- public int WorkedDay { get; set; }
- public enum LabourType { Fitter =1, Helper =2}
- }
-
- public class ContractBasis : Builder
- {
- public int TotalAmount { get; set; }
- public int DayComplited { get; set; }
- }
- }
Happy coding!