2009-04-01 1 views
13

Ich verwende den neuen .NET 3.0 DataContractSerializer. Ich habe beide Nullable < > und Liste <> Objekte, die ich serialisieren werde. Beispiel:Kann ich den DataContractSerializer so konfigurieren, dass optionale XML-Elemente (d. H. Nullable <> und List <>) nicht erstellt werden?

[DataContract(Namespace = "")] 
class Test 
{ 
    public static void Go() 
    { 
     Test test = new Test(); 

     var dcs = new DataContractSerializer(typeof(Test)); 
     dcs.WriteObject(new StreamWriter("test.xml").BaseStream, test); 
    } 

    [DataMember] 
    public Nullable<int> NullableNumber = null; 

    [DataMember] 
    public int Number = 5; 

    [DataMember] 
    public List<int> Numbers = new List<int>(); 
} 

Wenn .NET eine Null oder eine leere Liste serialisiert, bringt es auf null (für Nullable) und leer (für Listen) Elemente in die XML. Das oben gezeigte Beispiel erzeugt:

<Test xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> 
    <NullableNumber i:nil="true"/> 
    <Number>5</Number> 
    <Numbers xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays"/> 
</Test> 

Gründen ich keine Zeit haben, zu beschreiben, ich die überflüssigen NullableNumber und Zahlen Elemente eliminieren möchte, etwa so:

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

der Tat die oben genannten Datei deserialisiert mit dem Serializer geht es gut.

Danke für Ihre Hilfe!

Antwort

24

Markieren Sie das Feld mit

[DataMember(EmitDefaultValue=false)] 

Das ist für zumindest die Nullable-Wertetyp Fall funktionieren wird. Für den Listenfall müssen Sie möglicherweise die Erstellung der Liste aufschieben, bis sie benötigt wird, oder andernfalls das Element aufheben, wenn es vor der Serialisierung leer ist.

1

Ich brauchte wirklich die gleiche Sache, aber global auf viele Felder in generierten RIA-Klassen angewendet. Ich bin mir nicht sicher, ob dieses XML für DataSerial zum Deserialisieren akzeptabel ist. Aber es ist lesbar, was meinen Zwecken entspricht ...

public override string ToString() 
    { 
     var doc = XDocument.Parse(this.ToXML()); 
     WalkElement(doc.Root); 
     return doc.ToString(SaveOptions.None); 
    } 
    void WalkElement(XElement e) 
    { 
     var n = e.GetNamespaceOfPrefix("i"); 
     if (n != null) 
     { 
      var a = e.Attribute(n + "nil"); 
      if (a != null && a.Value.ToLower() == "true") 
       e.Remove(); 
     } 
     foreach (XElement child in e.Elements().ToList()) 
      WalkElement(child); 
    } 
Verwandte Themen