none
WCF CollectionDataContract and DataMember

    Question

  • In a collection that is marked as CollectionDataContract, is it possible to also have a DataMember?

     

    For example if I have :

     

    [CollectionDataContract]

    [KnownType(typeof(Entity))]

    public class EntityCollection : List<IEntity>, IEntityCollection, ITypedList

    {

      private IEntity entityPrototype_ = null;

      public EntityCollection() { }

     

      [DataMember]

      public IEntity EntityPrototype

      {

        get { return entityPrototype_; }

        set { entityPrototype_ = value; }

      }

    }

     

    The collection is serialized ok but the EntityPrototype is not.

    Thursday, November 15, 2007 2:54 PM

Answers

  • This is not supported in WCF. A possible workaround for this scenario would be to wrap the collection in a [DataContract] class and have the [DataMember] on that class.

     

    [DataContract]

    public class EntityCollectionWithPrototype

    {

        private EntityCollection collection_;

        private IEntity entityPrototype_ = null;

        [DataMember]

        public EntityCollection Collection

        {

            get { return collection_; }

            set { collection_ = value; }

        }

        [DataMember]

        public IEntity EntityPrototype

        {

            get { return entityPrototype_; }

            set { entityPrototype_ = value; }

        }

    }

    [CollectionDataContract]

    [KnownType(typeof(Entity))]

    public class EntityCollection : List<IEntity>, IEntityCollection, ITypedList

    {

        public EntityCollection() { }

    }

    Thursday, November 15, 2007 3:38 PM

All replies

  • This is not supported in WCF. A possible workaround for this scenario would be to wrap the collection in a [DataContract] class and have the [DataMember] on that class.

     

    [DataContract]

    public class EntityCollectionWithPrototype

    {

        private EntityCollection collection_;

        private IEntity entityPrototype_ = null;

        [DataMember]

        public EntityCollection Collection

        {

            get { return collection_; }

            set { collection_ = value; }

        }

        [DataMember]

        public IEntity EntityPrototype

        {

            get { return entityPrototype_; }

            set { entityPrototype_ = value; }

        }

    }

    [CollectionDataContract]

    [KnownType(typeof(Entity))]

    public class EntityCollection : List<IEntity>, IEntityCollection, ITypedList

    {

        public EntityCollection() { }

    }

    Thursday, November 15, 2007 3:38 PM
  • If your top-level type must stay a collection, you can also do something like this:

     

    [DataContract]

    [KnownType(typeof(Entity))]

    public class EntityCollection : IList<IEntity>, IEntityCollection, ITypedList

    {

      private IEntity entityPrototype_ = null;

      public EntityCollection() { }

     

      [DataMember]

      public IEntity EntityPrototype

      {

        get { return entityPrototype_; }

        set { entityPrototype_ = value; }

      }

     

      [DataMember(Name="Entities")]

      private List<IEntity> innerList;

     

     //Collection interface implementations go here and wrap innerList

    }

     

    Friday, November 16, 2007 9:54 PM
  • Eugene's suggestion won't work, since the innerList is "private" and private fields are not being serialized.

    Take a look at working solution on my blog:
    http://borismod.blogspot.com/2009/04/wcf-collectiondatacontract-and.html

    Sunday, April 19, 2009 8:47 AM

  • Here is a completely working class (also available at http://borismod.blogspot.com/2009/06/v2-wcf-collectiondatacontract-and.html )
    [DataContract]
      public classEntityCollectionWorkaround<EntityType> : ICollection<EntityType> 
      {
        #region Constructor
        public EntityCollectionWorkaround()
        {
          Entities = new List<EntityType>();
        } 
        #endregion

        [DataMember]
        public int AdditionalProperty { getset; }

        [DataMember]
        public List<EntityType> Entities { get;set; }

        #region ICollection<T> Members

        public void Add(EntityType item)
        {
          Entities.Add(item);
        }

        public void Clear()
        {
          this.Entities.Clear();
        }

        public bool Contains(EntityType item)
        {
          return Entities.Contains(item);
        }

        public void CopyTo(EntityType[] array, intarrayIndex)
        {
          this.Entities.CopyTo(array, arrayIndex);
        }

        public int Count
        {
          get
          {
            return this.Entities.Count;
          }
        }

        public bool IsReadOnly
        {
          get
          {
            return false;
          }
        }

        public bool Remove(EntityType item)
        {
          return this.Entities.Remove(item);
        }

        public EntityType this[int index]
        {
          get
          {
            return this.Entities[index];
          }
          set
          {
            this.Entities[index] = value;
          }
        }
        #endregion

        #region IEnumerable<T> Members

        public IEnumerator<EntityType> GetEnumerator()
        {
          return this.Entities.GetEnumerator();
        }

        #endregion

        #region IEnumerable Members

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
          return this.Entities.GetEnumerator();
        }

        #endregion
      }
    Monday, June 15, 2009 3:51 PM