Thursday, 16 April 2009

WCF CollectionDataContract and DataMember attributes

I came to write this post just occasionally: I was required to add a property to an existing collection. The colleciton was generated on the WCF and was sent to a client. I was surprised to discover, that it's not supported and other people already faced this issue and expressed their frustration and posted different workarounds on the web. Unfortunately, none of these suggestions worked. So I decided to post a tested solution.

So here is the situation, we have an Entity class and a collection of them:
using System.Collections.ObjectModel;
using System.Runtime.Serialization;
using System.Collections.Generic;

[DataContract]
public class Entity
{
public int ID {get; set;}
public int Name {get; set;}
}

[CollectionDataContract]
public class EntityCollectionNotSupported : Collection
{
[DataMember]
public int AdditionalProperty { get; set; }
}


* This source code was highlighted with Source Code Highlighter.


It will compile, but will not serialize AdditionalProperty at all! So what can we do about it if EntitiesCollection must stay a Collection?

We can mark our collection as DataContract and wrap another collection inside. Like this:

[DataContract]
public class EntityCollectionWorkaround : ICollection
{
public EntityCollectionWorkaround()
{
Entities = new List();
}

[DataMember]
public int AdditionalProperty { get; set; }

[DataMember]
public List Entities { get; set; }

// Implement here ICollection,
// IEnumerable and IEnumerable members
// by wrapping Entities
}


* This source code was highlighted with Source Code Highlighter.


Hope it helped somebody

3 comments:

Jeff Martin said...

Your comments:
// Implement here ICollection,
// IEnumerable and IEnumerable members
// by wrapping Entities

say IEnumerable twice and IEnumerable isn't implented at the class decoration...

Unknown said...

Thank you Jeff for your comment. My original intention was to derive my class from ICollection<T>. Thus I had to implement IEnumerable and IEnumerable<T>. I'll publish a full class in an additional post

Anonymous said...

This worked great thanks! I know it's an old post, but still help me out! :)