使用DataContractSerializer序列化子类实例的实用方法是什么?

时间:2011-06-13 15:31:23

标签: wcf serialization datacontract datacontractserializer

使用DataContractSerializer序列化子类实例的实用方法是什么?

例如,以下是数据类型:

 [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; }
    }

然后,这是创建具有两个不同车轮的汽车的代码:

    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);

现在,如果我尝试使用DataContractSerializer来序列化汽车,我将得到一个异常,说明不希望使用MichelinWheel。我必须像这样修改Wheel类才能使它工作:

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

但这种方法并不实用,因为我无法在创建之前列出所有类型的轮子。在创建新品牌的轮子后,每次更改Wheel类也是不切实际的,因为它们可能是通过第三方代码创建的。

那么,在使用DataContractSerializer时序列化子类实例的实用方法是什么?

由于

2 个答案:

答案 0 :(得分:4)

使用来自WCF 4的DataContractResolver检查this article。您还可以使用KnownTypeAttributepassing name of a method一起使用反射来获取所有类型。无论如何,服务要求所有类型在开始之前都是已知的。

答案 1 :(得分:1)

有几种方法可以使已知类型可用于该服务。

上面概述的最简单,但显然这需要您在添加新类型时重新编译,并且根据您的配置可能会使得避免循环依赖性变得尴尬。

您还可以配置KnownTypes: