16 Stimmen

Wie kann ich bei der Verwendung von ISerializable mit DataContractSerializer die Ausgabe von Typinformationen durch den Serializer verhindern?

Um mehr Kontrolle über die Serialisierung zu erhalten, habe ich eine Klasse von [DataContract] a [Serializable] , die beide GetObjectData und den speziellen Deserialisierungskonstruktor. Wenn ich dies tue, hat die XML emittiert jetzt Typinformationen für alle Elemente angewendet. Ich möchte nicht, dass diese überflüssigen Informationen, und ich frage mich, wie man den Serialisierer zu informieren, um es nicht auszugeben.

Hier ist der Beispielcode, der Folgendes 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);
        }
    }        
}

Dies gibt die folgende XML-Datei aus (beachten Sie, dass es keine Typinformationen zu Nullable Number und Number gibt - dies 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 ändere (Hinzufügen von [Serializable], : ISerializable und den 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);
    }
}

Er gibt nun die folgende XML-Datei aus. Beachten Sie die Typinformationen (i:type="x:int"), die jedem Element hinzugefügt wurden.

<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 tut sie das? Wie kann ich es aufhalten?

Merci !

1voto

Dmitry Kolchev Punkte 1998

Wenn Sie die volle Kontrolle über die Serialisierung in Xml haben möchten, können Sie XmlSerializer verwenden

public class Test
{
    [XmlIgnore]
    public Nullable<int> NullableNumber = 7;

    [XmlElement("NullableNumber")]
    public int NullableNumberValue
    {
        get { return NullableNumber.Value; }
        set { NullableNumber = value; }
    }

    public bool ShouldSerializeNullableNumberValue()
    {
        return NullableNumber.HasValue;
    }

    [XmlElement]
    public int Number = 5;
}

Beispiel für Serialisierungscode:

static void Main(string[] args)
{
    XmlSerializer serializer = new XmlSerializer(typeof(Test));
    serializer.Serialize(Console.Out, new Test());
}

Ergebnisse:

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

1voto

Martin Punkte 15472

Ab .Net Framework 4.5 (und .Net Core 1.0) ist dies mit der Option DataContractJsonSerializerSettings Klasse:

DataContractJsonSerializerSettings settings = new DataContractJsonSerializerSettings
{
    EmitTypeInformation = EmitTypeInformation.Never
};
var dcs = new DataContractSerializer(typeof(Test), settings);

Le site EmitTypeInformation Einstellungen sagt dem Serialisierer, dass er die (lästige?) __type Parameter während der Serialisierung.

Es gibt eine Reihe weiterer nützlicher Einstellungen. Hier ist die Dokumentseite para DataContractJsonSerializerSettings .

0voto

Marc Gravell Punkte 970173

Benötigen Sie die ISerializable hier? Was war die regelmäßige DataContractSerializer Ihnen nicht geben? Wenn Sie zu dieser Einstellung zurückkehren, sollte es problemlos funktionieren.

Grundsätzlich sind die Daten durch die Implementierung der benutzerdefinierten Serialisierung nicht mehr vertragsbasiert, so dass sie hat diese zusätzlichen Informationen aufzunehmen, um zu gewährleisten, dass er sie später verstehen kann.

Also: Gibt es einen Grund für die Einführung von ISerializable in diesem Fall?

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X