Search code examples
wcfserializationdatacontractdatacontractserializer

What's the practical way of serializing an instance of subclass by using DataContractSerializer?


What's the practical way of serializing an instance of subclass by using DataContractSerializer?

For example, here are the data types:

 [DataContract]
    public class Car
    {
        public Car()
        {
            Wheels = new Collection<Wheel>();
        }

        [DataMember]
        public Collection<Wheel> Wheels { get; set; }
    }

    [DataContract]    
    public abstract class Wheel
    {
        [DataMember]
        public string Name { get; set; }
    }

    [DataContract]
    public class MichelinWheel : Wheel
    {
        [DataMember]
        public string Wheel1Test { get; set; }
    }

    [DataContract]
    public class BridgeStoneWheel : Wheel
    {
        [DataMember]
        public string Wheel2Test { get; set; }
    }

Then here is the code that creates a car with two differen wheels:

    Car car = new Car();

    MichelinWheel w1 = new MichelinWheel { Name = "o1", Wheel1Test = "o1 test" };
    BridgeStoneWheel w2 = new BridgeStoneWheel { Name = "o2", Wheel2Test = "o2 test" };

    car.Wheels.Add(w1);
    car.Wheels.Add(w2);

Now if I try to serialize the car by using DataContractSerializer, I will get an exception that says MichelinWheel is not expected. And I have to modify the Wheel class like this to make it work:

 [DataContract]
    [KnownType(typeof(MichelinWheel))]
    [KnownType(typeof(BridgeStoneWheel))]
    public abstract class Wheel
    {
        [DataMember]
        public string Name { get; set; }
    }

But this approach is not practical, because I am not able to list all kinds of wheels before they are created. And changing the Wheel class every time after a new brand of wheel is created is also not practical, because they might by created in third-party code.

So, what is the practical approach of serializing an instance of a subclass when using DataContractSerializer?

Thanks


Solution

  • Check this article using DataContractResolver from WCF 4. You can also use KnownTypeAttribute with passing name of a method that will use reflection to get all types. Anyway service requires that all types are known before it starts.