使用 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 时序列化子类实例的实用方法是什么?
谢谢
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
使用 WCF 4 中的
DataContractResolver
查看本文您还可以将KnownTypeAttribute
与 传递将使用反射的方法的名称获取所有类型。无论如何,服务要求在启动之前了解所有类型。Check this article using
DataContractResolver
from WCF 4. You can also useKnownTypeAttribute
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.有多种方法可以使已知类型可供服务使用。
上面概述的最简单的方法,但显然这需要您在添加新类型时重新编译,并且根据您的配置可能会很难避免循环依赖。
您还可以配置 KnownTypes:
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: