2011-11-04 24 views
6

Solo deseo deserializar un determinado miembro de datos sin serializarlo.Cómo puedo evitar que un miembro de datos se serialice

Entiendo que puedo establecer EmitDefaultValue = false, y establecer el valor en nulo.

Pero tampoco quiero cambiar el valor del miembro de datos, ¿hay alguna otra forma de lograr esto?

El serializador es DataContractSerializer. :)

Gracias.

+2

No entiendo. ¿Cómo puede deserializar lo que no se serializa? – sehe

+1

@sehe He visto muchos escenarios donde se desea; no es raro –

+0

@MarcGravell: Ah, bueno, supongo que quiere decir que los datos podrían provenir de alguna otra fuente_. Pude ver que eso sucedía con la serialización de XML. Sin embargo, no es obvio (en general, no se puede deserializar lo que no se serializa) – sehe

Respuesta

7

Usted puede cambiar el valor del miembro de datos antes de la serialización (el valor por defecto, por lo que no consigue en serie), pero después de la serialización que cambiarla detrás - utilizando las devoluciones de llamada [OnSerializing] y [OnSerialized] (más información en this blog post). Esto funciona bien siempre que no tenga múltiples hilos serializando el objeto al mismo tiempo.

public class StackOverflow_8010677 
{ 
    [DataContract(Name = "Person", Namespace = "")] 
    public class Person 
    { 
     [DataMember] 
     public string Name; 
     [DataMember(EmitDefaultValue = false)] 
     public int Age; 

     private int ageSaved; 
     [OnSerializing] 
     void OnSerializing(StreamingContext context) 
     { 
      this.ageSaved = this.Age; 
      this.Age = default(int); // will not be serialized 
     } 
     [OnSerialized] 
     void OnSerialized(StreamingContext context) 
     { 
      this.Age = this.ageSaved; 
     } 

     public override string ToString() 
     { 
      return string.Format("Person[Name={0},Age={1}]", this.Name, this.Age); 
     } 
    } 

    public static void Test() 
    { 
     Person p1 = new Person { Name = "Jane Roe", Age = 23 }; 
     MemoryStream ms = new MemoryStream(); 
     DataContractSerializer dcs = new DataContractSerializer(typeof(Person)); 
     Console.WriteLine("Serializing: {0}", p1); 
     dcs.WriteObject(ms, p1); 
     Console.WriteLine(" ==> {0}", Encoding.UTF8.GetString(ms.ToArray())); 
     Console.WriteLine(" ==> After serialization: {0}", p1); 
     Console.WriteLine(); 
     Console.WriteLine("Deserializing a XML which contains the Age member"); 
     const string XML = "<Person><Age>33</Age><Name>John Doe</Name></Person>"; 
     Person p2 = (Person)dcs.ReadObject(new MemoryStream(Encoding.UTF8.GetBytes(XML))); 
     Console.WriteLine(" ==> {0}", p2); 
    } 
} 
+0

Muchas gracias. ¡Genial, esto funciona! – RKM

+0

Realmente ayudado. ¡Gracias! – Nobody

1

¿Ha intentado decorar la propiedad con [IgnoreDataMember]?

+0

Entonces no se deserializaría –

+0

gracias, Marc, eso es correcto, tampoco lo deserializará :( – RKM

4

Qué serializador Si esto es XmlSerializer entonces:?

public int Foo {get;set;} 
[XmlIgnore] 
public bool FooSpecified { 
    get { return false; } // never serialize 
    set { } 
} 

o

public int Foo {get;set;} 
public bool ShouldSerializeFoo() { return false; } 

hará esto. Una prueba rápida muestra que esto no funciona para DataContractSerializer, sin embargo. protobuf-net también es compatible con ambos, para obtener información.

+0

Marc, podría ¿vincula alguna documentación sobre eso o es indocumentado? Sin duda, solo curiosidad. – Marc

+0

@Marc hmmm .... molestamente, parece que es XmlSerializer solo –

+0

hola, gracias Mark, lamentablemente, es DataContractSerializer – RKM

0

Existe el atributo System.Xml.Serialization.XmlIgnoreAttribute que dice a xmkserializers que ignore su propiedad. Pero solo cambia el comportamiento de serialización xml.

+0

gracias, lo siento, no lo dije claro, esto no es serializador Xml, es DataContractSerializer. – RKM

0

añadir el IgnoreDataMemberAttribute

+0

gracias, pero parece ignorar al miembro de datos como un todo, es decir, tampoco lo serializaré. – RKM

Cuestiones relacionadas