2011-11-04 159 views
6

我只想仅对序列化某个数据成员进行反序列化。如何防止数据存储器被序列化

我明白我可以设置EmitDefaultValue = false,并将值设置为null。

但我也不想改变数据存储的价值,有没有其他的方式来实现这一点?

序列化程序是DataContractSerializer。 :)

谢谢。

+2

我不明白。你如何反序列化没有序列化的东西? – sehe

+1

@sehe我已经看到了很多场景,这是所需的;这并不罕见 –

+0

@MarcGravell:哦,好吧,我想你的意思是这些数据可能来自_some other source_。我可以看到这发生在XML序列化。然而,它并不明显(一般来说,你不能反序列化没有序列化的东西) – sehe

回答

7

您可以将串行化之前更改数据成员的值(默认值,因此它没有被序列化),但随后的序列化之后你会改回来 - 使用[OnSerializing][OnSerialized]回调(更多信息请参阅this blog post)。只要您没有多个线程同时序列化对象,此工作正常。

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

非常感谢。太棒了,这个作品!!! – RKM

+0

真的帮了忙。谢谢! – Nobody

1

您是否尝试过使用[IgnoreDataMember]来装饰房产?

+0

然后它不会反序列化 –

+0

谢谢,马克,这是正确的,它不会反序列化它:( – RKM

4

哪个串行如果这是XmlSerializer然后:?

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

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

会做到这一点。一个快速测试表明,这不适用于DataContractSerializer,但。对于信息,protobuf-net也支持这两种。

+0

马克,可以 – Marc

+0

@Marc嗯....烦人的是,它看起来像是XmlSerializer只有 –

+0

嗨,感谢马克,不幸的是,它是DataContractSerializer – RKM

0

有属性System.Xml.Serialization.XmlIgnoreAttribute至少说xmkserializers忽略你的财产。但它只会改变xml序列化行为。

+0

谢谢,对不起,我没有说清楚,这不是Xml序列化程序,它是DataContractSerializer。 – RKM

0

添加IgnoreDataMemberAttribute

+0

谢谢,但它似乎忽略整个数据库,也就是说不会反序列化它 – RKM