4

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

Sam Holder
  • 32,535
  • 13
  • 101
  • 181
Cui Pengfei 崔鹏飞
  • 8,017
  • 6
  • 46
  • 87

2 Answers2

5

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.

Ladislav Mrnka
  • 360,892
  • 59
  • 660
  • 670
1

There are several ways to make known types available to the service.

The simplest you have outlined above, but obviously this requires you to recompile when new types are added, and depending on your configuration can make it awkward to avoid circular dependencies.

You can also configure the KnownTypes:

Community
  • 1
  • 1
Sam Holder
  • 32,535
  • 13
  • 101
  • 181