2009-04-02 4 views
8

Um mehr Kontrolle über die Serialisierung zu bekommen, habe ich eine Klasse von [DataContract] in [Serializable] konvertiert, indem ich sowohl GetObjectData als auch den speziellen Deserialisierungskonstruktor implementiert habe. Wenn ich das tue, hat das ausgesendete XML jetzt Typinformation, die auf alle Elemente angewendet wird. Ich möchte diese überflüssige Information nicht, und ich frage mich, wie ich den Serialisierer informieren soll, es nicht auszugeben.Wie kann ich beim Verwenden von ISerializable mit DataContractSerializer die Ausgabe von Typinformationen stoppen?

Hier ist der Beispielcode, der verwendet [Datacontract]:

[DataContract(Namespace = "")] 
class Test 
{ 
    public Test() { } 
    [DataMember] 
    public Nullable<int> NullableNumber = 7; 
    [DataMember] 
    public int Number = 5; 

    public static void Go() 
    { 
     var test = new Test(); 
     var dcs = new DataContractSerializer(typeof(Test)); 
     using (var s = new StreamWriter("test.xml")) 
     { 
      dcs.WriteObject(s.BaseStream, test); 
     } 
    }   
} 

Das gibt das folgende XML (auf Nullable Anzahl und Anzahl keine Art Info bemerken - das ist die gewünschte Ausgabe):

<Test xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> 
    <NullableNumber>7</NullableNumber> 
    <Number>5</Number> 
</Test> 

Wenn ich den obigen Code wie folgt ändern (Hinzufügen von [Serializable]: ISerializable, und die beiden Serialisierungsmethoden):

[Serializable] 
class Test : ISerializable 
{ 
    public Test() { } 
    public Nullable<int> NullableNumber = 7; 
    public int Number = 5; 

    public static void Go() 
    { 
     var test = new Test(); 
     var dcs = new DataContractSerializer(typeof(Test)); 
     using (var s = new StreamWriter("test.xml")) 
     { 
      dcs.WriteObject(s.BaseStream, test); 
     } 
    }   
    public Test(SerializationInfo info, StreamingContext context) 
    { 
     NullableNumber = info.GetInt32("NullableNumber"); 
     Number = info.GetInt32("Number"); 
    } 

    public void GetObjectData(SerializationInfo info, StreamingContext context) 
    { 
     info.AddValue("NullableNumber", NullableNumber); 
     info.AddValue("Number", Number); 
    } 
} 

Es gibt jetzt das folgende XML aus. Beachten Sie, dass die Typinformationen (i: type = "x: int") zu jedem Element hinzugefügt werden.

<Test xmlns="http://schemas.datacontract.org/2004/07/XMLSerialization" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:x="http://www.w3.org/2001/XMLSchema"> 
    <NullableNumber i:type="x:int" xmlns="">7</NullableNumber> 
    <Number i:type="x:int" xmlns="">5</Number> 
</Test> 

Warum macht es das? Wie halte ich es davon ab?

Danke!

+0

Vielen Dank für die Frage, weil es meine Frage gelöst hat :-) Wie für "warum" - im ersten Beispiel gab es eine Garantie, jeder Eintrag ist ein Feld, so können Sie den Typ des Feldes nur durch nachsehen bei "Test" -Typ. Im zweiten Fall haben ** Sie ** die Kontrolle, so dass diese Einträge keine Felder sein müssen, Sie könnten nur zufällige Daten schreiben/lesen. – astrowalker

Antwort

0

Benötigen Sie die ISerializable hier? Was hat dir der normale DataContractSerializer nicht gegeben? Wenn Sie zurückschalten, sollte es gut funktionieren.

Grundsätzlich durch benutzerdefinierte Serialisierung Implementierung sind die Daten nicht mehr Vertrag beruht - so es hat diese zusätzliche Informationen aufzunehmen, um sicherzustellen, dass es in der Lage ist, es später zu verstehen.

Also: Gibt es einen Grund, ISerializable in diesem Fall zu implementieren?

+0

Ich habe das Beispiel verkleinert, um die Frage zu vereinfachen. Ich brauche benutzerdefinierte Serialisierung aus Gründen, die ich hier nicht zeige. – Eric

+0

Von der (langen Liste) von Gründen brauche ich benutzerdefinierte Serialisierung, die größte ist, dass ich bestimmte Eigenschaften basierend auf anderen Informationen bedingt ausgeben muss. – Eric

+1

Ich verstehe nicht Ihren Kommentar über "es hat" diese zusätzliche Informationen zu enthalten ". In der Tat entschlüsselt das erste obige XML-Beispiel den Deserializer [Serializable] sehr gut, so dass der Deserializer diese Art von Informationen nicht benötigt. – Eric

Verwandte Themen