使用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]
    [K@R_502_6363@nType(typeof(MichelinWheel))]
    [K@R_502_6363@nType(typeof(BridgeStoneWheel))]
    public abstract class Wheel
    {
        [DataMember]
        public string Name { get; set; }
    }
但是这种方法不切实际,因为在创建它们之前,我无法列出所有类型的轮子。而且,在创建新品牌的轮之后每次更改Wheel类也是不切实际的,因为它们可能是由第三方代码创建的。 那么,使用DataContractSerializer时序列化子类实例的实际方法是什么? 谢谢     

解决方法

        使用WCF 4中的
DataContractResolver
查看本文。您也可以将
KnownTypeAttribute
与方法的传递名称一起使用,该方法将使用反射来获取所有类型。无论如何,服务需要在启动之前知道所有类型。     ,        有几种方法可以使已知类型对服务可用。 上面已经概述了最简单的方法,但是显然,这需要您在添加新类型时重新编译,并且根据您的配置,它可能会很尴尬,从而避免循环依赖。 您还可以配置KnownTypes: 通过服务配置文件(仅需要重新启动服务), 将它们添加为通过服务接口上的静态方法提供的服务已知类型,您可以通过Ladislav Mrnka指出的方式进行反射(您可能会反射所有已加载的程序集,并将所有具有DataContact属性的类型返回为已知类型,但我找不到这样的例子。) 实现您自己的获取方式(也许通过配置文件中的某些定制配置元素,或仅通过文本文件)