2011-12-02 5 views
6

nell'applicazione Silverlight 4, I Serializzare/Deserializzare i dati con DataContractSerializer. Posso avere due diversi tipi di dati: EditorModel e ConfiguratorModel. Entrambi i modelli ereditano da una comune baseclass.Deserializzare la classe ereditata con DataContractSerializer (typeof (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 { ... } 

La serializzazione non è un problema e funziona come previsto. Quando deserializzo, non voglio nominare la classe ereditata specifica, perché l'utente può caricare anche EditorModel o ConfiguratorModel. Ho trovato this stackoverflowquestion, risposto da Marc Gravell e, a quanto ho capito, posso usare la classe base quando conosce i tipi ereditati (cosa che fa, vedere la Dichiarazione di KnownType su DTO_ServiceModelBase).

Eppure, quando faccio la seguente deserializzazione (ho anche aggiunto entrambi i tipi ereditati come secondo parametro):

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) 
{ .. } 

viene generata un'eccezione, perché si aspetta "ServiceModel" ma ha trovato "ServiceModelEditor". C'è qualcosa che ho dimenticato, o ho sbagliato la risposta di Marc?

Grazie in anticipo,
Frank

risposta

5

Come va la serializzazione? Quando si sta serializzando, si dovrà specificare che si stanno scrivendo gli oggetti della classe base DTO_ServiceModelBase e che quindi dovrebbe funzionare. Così, quando sei serializzazione solo definire la DataContractSerialiser nello stesso modo come nel tuo esempio deserialisation:

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

Da l'errore sembra che hai fatto qualcosa di simile a questo, invece:

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

Questo dovrebbe sono stati contrassegnati come la risposta corretta. –