2009-04-01 7 views
13

Estoy usando el nuevo .NET 3.0 DataContractSerializer. Tengo tanto Nullable < > y List <> objetos que voy a serializar. Ejemplo:¿Puedo configurar DataContractSerializer para que no cree elementos opcionales (es decir, Nullable <> y List <>) en XML de salida?

[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>(); 
} 

Cuando .NET serializa un nulo o una lista vacía, se pone en nil (por Anulable) y vacío (para listas) elementos en el XML. El ejemplo anterior genera:

<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> 

Por razones que no tengo tiempo para describir quisiera eliminar los elementos superfluos NullableNumber y números, así:

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

De hecho, los Deserializa archivo anteriores con el serializador bien.

Gracias por su ayuda!

Respuesta

24

Marque el campo con

[DataMember(EmitDefaultValue=false)] 

que funcionará durante al menos el caso de tipo de valor anulable. Para el caso de la Lista, es posible que deba diferir la creación de la lista hasta que sea necesaria, o bien anule el miembro si está vacío antes de la serialización.

1

Realmente necesitaba lo mismo, pero se aplica globalmente a muchos campos en las clases de RIA generadas. No estoy seguro de si este XML es aceptable para DataConstract por deserializar. Pero es legible, lo que se adapta a mis propósitos ...

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); 
    } 
Cuestiones relacionadas