使用 DataContractSerializer(typeof(BaseClass)) 反序列化继承类
在我的 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 声明)。
尽管如此,当我执行以下反序列化时(我还添加了两种继承类型作为第二个参数):
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”。我是否忘记了什么,或者我是否听错了马克的答案?
预先感谢,
坦率
in my Silverlight 4 application, I Serialize/Deserialize data with DataContractSerializer. I can have two different types of data: The EditorModel and the ConfiguratorModel. Both models inherit from a common baseclass.
[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 { ... }
Serializing is no problem and works as intended. When I deserialize, I do not want to name the specific inherited class, because the user can load EditorModel or ConfiguratorModel as well. I found this stackoverflowquestion, answered by Marc Gravell, and as I understand it, I can use the base class when it knows the inherited types (which it does, see the KnownType-Declaration at DTO_ServiceModelBase).
Still, when I do the following Deserialization (I also added both inherited types as the second parameter):
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)
{ .. }
It throws an exception, because it expects "ServiceModel" but found "ServiceModelEditor". Is there anything I forgot, or did I got Marc's answer wrong?
Thanks in advance,
Frank
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
你的连载工作进展如何?当您进行序列化时,您必须指定您正在写出基类 DTO_ServiceModelBase 的对象,然后它应该可以工作。因此,当您进行序列化时,只需按照与反序列化示例中相同的方式定义 DataContractSerialiser 即可:
从错误看来,您似乎已经做了类似的事情:
How are you doing the serialisation? When you're serialising you'll have to specify that you're writing out objects of the base class DTO_ServiceModelBase and then it should work. So when you're serialising just define the DataContractSerialiser the same way as in your deserialisation example:
From the error it looks as though you've done something like this instead: