Serializing types that return interfaces instead of instances in WCF 3.5 SP1

April 7, 2009 by · Leave a Comment
Filed under: Programming, Software Configuration, WCF 

I came across interesting problems with WCF serialization specifically the DataContractSerializer and limitations of the runtime.

Say you have a class like so

[Serializable]

    public class Service

    {

        public IList<Person> People

        {

            get; set;

        }

    }

   

    [Serializable]

    public class Person

    {

        public string Name

        { get; set; }

       

        public string Address

        { get; set; }

    }

 

 

 

 If you try to get this working in a WCF service it won’t work, basically the problem is that you are returning an interface, not a concrete type, and the serializer doesn’t know how to deal with it. To allow this to work you basically have to implement a data contract for the types invovled, then it seems to understand, and also adding a KnownType attribute helps it to serializer things without getting generic random errors on the service.

    [ServiceContract]

    [KnownType(typeof(Person))]

    public class Service

    {

        [DataMember]

        public IList<Person> People

        {

            get; set;

        }

    }

 

    [DataContract]

    public class Person

    {

        [DataMember]

        public string Name

        { get; set; }

       

        [DataMember]

        public string Address

        { get; set; }

    }

 

 

Another common issue is that best practices say your shouldn’t have setters on a collection, but let users add to it or remove, from the collection itself.   the WCF serializer requires read/write access to the collection for its duty, so a way around it is to do this

    [ServiceContract]

    [KnownType(typeof(Person))]

    public class Service

    {

        [DataMember(Name = “People”)]

        private List<Person> people = new List<Person>();

 

       

        public IList<Person> People

        {

            get

            {

                return people;

            }

        }

    }

   

    [DataContract]

    public class Person

    {

        [DataMember]

        public string Name

        { get; set; }

       

        [DataMember]

        public string Address

        { get; set; }

    }