Thursday, 28 May 2015

DataMember Attributes of WCF Data Contract

Using this article you will know what are the data member attributes and enum member attributes can be used for effective data contract design.
[DataMember] attribute needs to be marked for every fields, methods or properties of [DataContract] to make it serializable by DataContractSerializer for service request and response. DataMember properties cannot be read only or write only, it must include getter and setter. DataMember is included in System.Runtime.Serilization assembly. DataMember is a sealed class.

DataMember has below attributes.
1.  

EmitDefaultValue
DataMember EmitDefaultValue is Boolean attribute with default value of true. If the value is not provided for DataMember then the corresponding default value will be set to the member for example integer it will be set as 0, for bool it is false, any reference type it is null. If you do not want to use the default value to set then mark this attribute to false. Marking this as false will help you for reducing request response size and better interoperability.
[DataContract]
public class Order
{
    // This will be written as <OrderQty>1</OrderQty>
    [DataMember]
    public int OrderQty = 1;

    //This member not be deserialize
    //as it is EmitDefaultValue = false.
    [DataMember(EmitDefaultValue = false)]
    public double OrderTotal = 0.0;

    [DataMember(EmitDefaultValue = false)]
    public string CustomerName = string.Empty;
}
           


2.  IsRequired
DataMember IsRequired is Boolean attribute with default value of false. If the value for DataMember is required then set it to true else mark it as false. If IsRequired is marked as true with EmitDefaultValue as true and value is not provided while serialization then the default value will be emitted. If IsRequired is marked as true with EmitDefaultValue as false and value is not provided while serialization then SerializationException will be thrown.
[DataContract]
public class Order
{
    // This will be written as <OrderQty>1</OrderQty>
    [DataMember(IsRequired = false)]
    public int OrderQty = 1;
}       
           
Changing this attribute from false to true will be a breaking change to existing client communications however changing it from false to true will not break.


3.  Name
DataMember Name is string attribute with default value as name of method to which it is applied. The DataMember name property is helpful to handle some of the DataContract version issues. Some data contract changes will break the existing client communication like changing DataMember name, changing DataContract name or namespace, changing the order of DataMembers. In following example the change to Name DataMember will not be breaking change to existing client communication.
// Version 1 of DataContract Order
[DataContract]
public class Order
{
    [DataMember]
    private string OrderID;  

    [DataMember]
    private string Name;  
}

// Version 2 of DataContract Order
[DataContract]
public class Order
{
    [DataMember]
    private string OrderID;  

    [DataMember(Name = "Name")]
    private string CustomerName;  
}
           
The addition or deletion of DataMember with IsRequired = false and EmitDefaultValue = true will not break any existing clients. 

Setting the Name property will also be helpful when you are having inheritance for DataContract with same DataMember name.


4.  Order
DataMember Order attribute is of type integer. Sometime DataContract should serialized or deserialized in specific order of DataMembers. By default DataMembers are serialized or deserialized in below order.
o    1. If DataContract has derived from base DataContract so the DataMembers from base class will process first in alphabetical order.
o    2. DataMembers with no Order property set will process in alphabetical order.
o    3. Remaining DataMembers will be processed in ascending order of Order property value.
Enumeration Types in Data Contracts
·         EnumMemberAttribute allows you to create new Enumeration for DataContract. For marking the enum member use [EnumMember] to members. All the members which are required in serialization and deserialization must mark as [EnumMember].
·         Following is an example of how to use enum in DataContract. Setting value for Status DataMember to Completed will result in SerializationException as it is not marked with [EnumMember].
[DataContract]
public class Order
{
    [DataMember]
    public int OrderID;

    [DataMember]
    public Status OrderStatus;
}

[DataContract(Name = "Status")]
public enum Status
{
    [EnumMember]
    Created,

    [EnumMember]
    Shipped,

    [EnumMember]
    Delivered,

    Completed
}
   
EnumMemberAttribute has below attributes.
1.  Value
EnumMember value is string property with default value of the name of enum member to which it is applied. In above example setting DataMember Status = Delivered will result below xml. 
<Status>Delivered</Status>
 

Setting the value to enum member will replace the actual text.
[DataContract(Name = "Status")]
public enum Status
{
    [EnumMember(Value="1")]
    Created,

    [EnumMember(Value="2")]
    Shipped,

    [EnumMember(Value="3")]
    Delivered
}
            
With above Enum set DataMember Status = Delivered will result below xml. 
<Status>3</Status>


No comments:

Post a Comment