2012-10-12 13 views
5

In Assembly A nicht bekannt:Deserialisieren abgeleiteten Typ DataContractSerializer verwenden, wenn abgeleiteten Typ wird vorher

[DataContract]  
     public class Base 
     { 
      [DataMember] 
      public string SomeText { get; set; } 
     } 

In Assembly B:

internal class Helper 
     { 
      internal static Base Deserialize(string serializedInstanceOfTypeBase) 
    { 
        DataContractSerializer serializer = new DataContractSerializer(typeof (Base)); 
        XmlReader reader = XmlReader.Create(new StringReader(serializedInstanceOfTypeBase)); 
        return (Base)serializer.ReadObject(reader); 
    } 
    } 

In Assembly C:

Wenn ich eine Instanz vom Typ Derived serialisiert werden und es zu Helper.Deserialize() Methode übergeben, schlägt es mit dem SerializationException:

Fehler in Zeile 1 Position 2 Expecting Element 'Base' aus Namespace ‚http: // Schemas .datacontract.org/2004/07 '.. Encountered' Element ' mit dem Namen' Derived ', Namespace ' http://schemas.datacontract.org/2004/07 '.

Wie kann ich dieses Problem beheben?

Ich bin mir der KnownType Attribut bewusst, aber zum Zeitpunkt der Codierung in Assembly A und B, bin ich absolut nicht bewusst, seine abgeleiteten Typen. Also kann ich diese Lösung nicht verwenden.

Design meines Produkts ist komplexer, die ich hier nicht vollständig veröffentlichen kann. Helper.Desrialize() Methode erhält nur ein string Argument. Es gibt keine Möglichkeit (derzeit zumindest) für Baugruppe A oder B, abgeleitete Typen der Klasse Base zu kennen, auch zur Laufzeit.

Assembly B Referenzen Montage A. But A & B kann nicht Baugruppe C Referenz

Ich bin mit C# 4.0. Es ist in Ordnung, wenn die von Ihnen bereitgestellte Lösung DataContractSerializer NICHT verwendet.

+1

Ich weiß nicht über eine Out-of-the-Box-Lösung. Ich weiß in meiner Erfahrung, wenn ich eine große Vielfalt von Typen hatte, würde ich meinen Inhalt tatsächlich mit Typinformation doppel-serialisieren. Das heißt, ich hätte ein 'SerializedObject', das vollständige Typinformationen (Assemblyname, vollständiger Klassenname) zusammen mit seiner serialisierten XML-Zeichenfolge enthalten würde.Meine Datenübertragungsschicht würde sich stark gegen 'SerializedObject' einschreiben, einen Laufzeitverweis auf den Typ abgreifen (etwa über' Type.GetType'), und dann die XML-Daten über einen XmlSerializer entsprechend deserialisieren. –

+0

Sie meinen "Base" -Klasse ist in "Assembly A" und "Derived" -Klasse ist in "Assembly C"? Wenn das so ist, dann denke ich, das ist das Problem. Die Datenverträge sollten in derselben Baugruppe definiert werden. Die DataContracts sollten nicht auf Baugruppen aufgeteilt werden. – jags

Antwort

2

Kennen Sie die Typen zur Laufzeit? Wenn ja, könnte ein einfacher Ansatz nur sein:

List<Type> knownTypes = ...; // now that you know what to expect 
DataContractSerializer serializer = new DataContractSerializer(
    typeof(Base), knownTypes); 
+0

Danke für Ihre Antwort. Es ist sehr hilfreich, aber ich habe mehr Details zu der Frage hinzugefügt. Ich hätte diese Details vorher hinzufügen sollen. Beachten Sie, dass die 'Helper'-Klasse sich in einer anderen Assembly befindet und nicht 'public' ist. Außerdem erhält die 'Deserialize'-Methode nur einen beliebigen Zeichenfolgenwert. – Learner

Verwandte Themen