使用DataContractSerializer(typeof(BaseClass))反序列化继承类

本文关键字:反序列化 继承 BaseClass DataContractSerializer typeof 使用 | 更新日期: 2023-09-27 18:16:42

在我的Silverlight 4应用程序中,我使用DataContractSerializer序列化/反序列化数据。我可以有两种不同类型的数据:EditorModel和ConfiguratorModel。两个模型都继承自一个公共基类。

[DataContract(IsReference = true, Name = "ServiceModel", Namespace = "ServiceModeller.DataModel.Serialization")]
[KnownType(typeof(DTO_ServiceModelEditor))]
[KnownType(typeof(DTO_ServiceModelConfigurator))]
public abstract class DTO_ServiceModelBase { ... }
[DataContract(IsReference = true, Name = "ServiceModelEditor", Namespace = "ServiceModeller.DataModel.Serialization")]
public class DTO_ServiceModelEditor : DTO_ServiceModelBase { ... }
[DataContract(IsReference = true, Name = "ServiceModelConfigurator", Namespace = "ServiceModeller.DataModel.Serialization")]
public class DTO_ServiceModelConfigurator : DTO_ServiceModelBase { ... }

序列化没有问题,并按预期工作。当我反序列化时,我不想命名特定的继承类,因为用户也可以加载EditorModel或ConfiguratorModel。我发现了这个stackoverflowquestion,由Marc Gravell回答,正如我所理解的,当基类知道继承类型时,我可以使用它(它确实知道,参见DTO_ServiceModelBase中的KnownType-Declaration)。

但是,当我执行以下反序列化时(我还添加了两个继承类型作为第二个参数):

DataContractSerializer serializer = new DataContractSerializer(typeof(DTO_ServiceModelBase), new Type[] {typeof(DTO_ServiceModelEditor), typeof(DTO_ServiceModelConfigurator)} );
System.Xml.XmlReader reader = System.Xml.XmlReader.Create(new System.IO.StringReader(stream));
// stream is the serialized string
object result;
try
{
  result = serializer.ReadObject(reader);
}
catch (Exception ex)
{ .. }

它抛出一个异常,因为它期望"ServiceModel",但发现"ServiceModelEditor"。是我忘了什么吗,还是我把马克的答案搞错了?

提前感谢,
弗兰克。

使用DataContractSerializer(typeof(BaseClass))反序列化继承类

您是如何进行序列化的?当你序列化时,你必须指定你正在写出基类DTO_ServiceModelBase的对象,然后它应该工作。因此,当你在序列化时,只需定义DataContractSerialiser就像在反序列化示例中一样:

DataContractSerializer serializer = new DataContractSerializer(typeof(DTO_ServiceModelBase), new Type[] {typeof(DTO_ServiceModelEditor), typeof(DTO_ServiceModelConfigurator)} );

从错误中看起来好像你做了这样的事情:

DataContractSerializer serializer = new DataContractSerializer(typeof(DTO_ServiceModelEditor));