Deserialize Inherited class with DataContractSerializer(typeof(BaseClass))
Asked Answered
C

1

6

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

Catachresis answered 2/12, 2011 at 10:51 Comment(0)
E
5

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:

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

From the error it looks as though you've done something like this instead:

DataContractSerializer serializer = new DataContractSerializer(typeof(DTO_ServiceModelEditor));
Ethics answered 23/1, 2012 at 4:45 Comment(1)
This should have been marked as the correct answer.Krohn

© 2022 - 2024 — McMap. All rights reserved.