Showing posts with label WCF Data contracts. Show all posts
Showing posts with label WCF Data contracts. Show all posts

Wednesday, February 11, 2009

Windows Commuication Foundation(WCF) Data Contract serialization techniques

WCF 3.5 supports two types of serialization techniques.
  • DataContractSerializer
  • XmlSerializer

DataContractSerializer Vs XMLSerializer

In contrast to predecessor XmlSerializer, DataContractSerializer serializes only members declared explicitly using DataMember attribute. XmlSerializer serializes all members of data contract except for members declared explicitly using NotSerialized attribute.

WCF Serialization Caveats:

.Net Built-in collection types and custom collections implementing IEnumerable or IEnumerable interfaces are represented as Arrays type when serialized across wire which means they appear as arrays to the clients.

To serialize a custom collection defined in data contract, few things we need to understand are:

  • Collection in the contract must be a concrete collection(not an interface) and is serializable
  • Collection should contain an Add operation

if we satisfy above requirements, WCF automatically serialize the collection as an array of collection's type.

If your collection doesn't meet above requirements, there's a still way to serialize the collections using CollectionDataContractAttribute. You can use this attribute to annotate your custom collections and resulting collections will always be exposed as List collection to it's WCF consumers.

As mentioned in my earlier post, Data Contracts doesn't support inheritance hierarchy. we have to explicitly annotate derived classes with DataContract attribute. Let's know something more about another important attribute in this context.

KnownTypeAttribute:

For instance, we have a derived class called car derived from base class called vehicle. When you pass in a car object instead of vehicle object, the service doesn't know how to deserialize the car object it received, because it doesn't know about car object.

Much the same way, when a car object is returned instead of a vehicle, the client doesn't know how to deserialize it, because all it about are vehicles but not cars.

The solution is to explicitly tell WCF about the car class using the KnownTypeAttribute attribute. The KnownType attribute allows you to designate sub classes for the data contract of base class.

Polymorphism is outside the paradigm of Service orientation. So, KnownTypeAttribute is required to specify derived class relationship with base class for DataContract Serializer.

We've to annotate base class with KnownTypeAttribute for all those derived classes being utilized in the data contract.

Tuesday, February 10, 2009

WCF Data contracts

Before we understand Windows Communication Foundation (WCF) Data contracts, let's first set the context of data representation and various forms of it. Dimensions of information exchange is changed drastically these days. Ok, when two parties communicate or exchange data electronically, how do they manage communication? They usually define common protocols, standards or agreements over data format or representation before they actually exchange data with each other.

That said, you may ask what are those different standards or representations. I can think for now in XML world what we call is XSD (XML Schema Definition) language. Using XSD, we define structure of data, types of data and format of the data. You may also recall DOM (Document Object Model) mechanism which is also used to represent structure.

In Service Oriented Architecture (SOA) paradigm, loosely coupled services play a major role. Consumers request services for data using standardized SOAP messages or you also invoke services using latest REST based protocol. In this request/response exchange, data needs to be represented in proper format for both client and server to interact properly.

Windows communication Foundation (WCF) defines some thing called Data Contracts. Data contracts define the structure of payload data in soap message exchanged. Data contracts enable serialization of complex types included in request /response messages.

How do we define Data Contracts?

  • Datacontract attribute is declared in System.Runtime.Serialization namespace in .Net Framework.
  • This attribute can be applied to structs, enums and classes.
  • Data contracts are not inherited. Any inherited data contract must have attribute specified explicitly
  • By Default, DataContractSerializer performs serialization of data contracts to enable transmission of data contracts between client & server.

What is Data Member?

DataMember attribute is declared in the same namespace as DataContract attribute. We can apply this attribute to members in data contract to indicate they should be included in serialization.

It supports two attributes:

IsRequired: Indicates whether a member is optional. Default value is false. this attribute is very useful in Data contract versioning scenarios. For instance, your service expects a new version of data contract in which new fields are added. The client is not aware of these changes. Clients send his request using old data contract which doesn't break at the service. Service successfully processes his request. This is happened because service is not expecting values for new fields from client since IsRequired is set to false by default on new fields unless you explicitly set them to required.

EmitDefaultValue: Controls whether default values will be included if no values are supplied for the members. Default value for this attribute is true which means all data members are serialized. If attribute is set to false, any member with out any valid data value or with any default value ( Ex: null value for reference types) will not be serialized.

These two properties work in tandem. Like, Having EmitDefaultValue property set to false and setting IsRequired to true can cause problems if you don't provide any valid value for member.

Just apply Datamember attribute to only properties if field is associated with the property.

Ordering precedence for elements in DataContracts:

If datacontract is part of inheritance hierarchy, then members of base type are listed first followed by current type members sorted alphabetically. Next are any members that have the order property set.

EnumMember Attribute:

Enumerations still should be defined using Data contract attribute as mentioned earlier. Only enumeration member should be only decorated with EnumMember attribute.

EnumMember attribute is used to declare that given member of enumeration declared with a data contract attribute should be considered as part of data contract. Only property for this attribute is Value

We'll discuss more about DataContractSerializer and XML Serializer which are used to serialize data contracts in our next post.

Hope this post is useful to you.