Showing posts with label DataContractSerializer. Show all posts
Showing posts with label DataContractSerializer. Show all posts

Tuesday, January 19, 2010

WCF errors: Type 'xxx' is an invalid collection type since it has DataContractAttribute attribute.

If you have ever happen to get "Type xxx is an invalid collection type since it has DataContract Attribute attribute" error at any time when ever publishing WCF service, Make sure you annotate your custom collections with CollectionDataContract attribute instead of DataContract attribute. This attribute will appropriate serialize and deserialize collection.


CollectionDataContract attribute is typically utilized in scenarios involving non-WCF providers/clients to extract exact shape of data. But, you loose one important benefit with "CollectionDataContract" is "Cross Collection Interchangeability". For instance, in case of homogeneous environment of WCF client and service though WCF service exposes List collections as response, client expecting different native collection type like ArrayList/Collection can still consume the collection.


You loose this benefit if you use CollectionDataContract attribute with Collection Types.

WCF also imposes additional requirements when using collections. Keep in mind of following items when exposing custom collections via WCF service or else custom collections are not serialized/deserialized.


  • Collection should support Add method.
  • Collection should have default constructor.



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.