【问题标题】:How can I prevent a datamember from being serialized如何防止数据成员被序列化
【发布时间】:2011-11-04 14:22:43
【问题描述】:

我只想反序列化某个数据成员,而不对其进行序列化。

我知道我可以设置 EmitDefaultValue =false,并将值设置为 null。

但我也不想更改数据成员的值,有没有其他方法可以实现这一点?

序列化器是 DataContractSerializer。 :)

谢谢。

【问题讨论】:

  • 我不明白。如何反序列化未序列化的内容?
  • @sehe 我见过很多需要这样做的场景;这并不罕见
  • @MarcGravell:哦,好吧,我猜你的意思是数据可能来自其他来源。我可以看到 XML 序列化正在发生这种情况。但是,这并不明显(通常,您无法反序列化未序列化的内容)

标签: c# serialization


【解决方案1】:

您可以在序列化之前更改数据成员的值(更改为默认值,因此它不会被序列化),但是在序列化之后您可以将其改回 - 使用 [OnSerializing] 和 @987654323 @回调(更多信息在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);
    }
}

【讨论】:

  • 真的很有帮助。谢谢!
【解决方案2】:

哪个序列化器?如果这是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 也支持这两者,供参考。

【讨论】:

  • Marc,你能链接一些关于它的文档还是没有文档?不怀疑,只是好奇。
  • @Rosie 我确信 DCS 支持类似的东西。我稍后再看。
【解决方案3】:

你试过用[IgnoreDataMember]装饰房子吗?

【讨论】:

  • 那么它也不会反序列化
  • 谢谢,Marc,没错,它也不会反序列化它:(
【解决方案4】:

有一个属性 System.Xml.Serialization.XmlIgnoreAttribute 告诉 xmkserializers 忽略你的属性。但它只会改变 xml 序列化行为。

【讨论】:

  • 谢谢,对不起,我没有说清楚,这不是 Xml 序列化器,它是 DataContractSerializer。
【解决方案5】:

添加IgnoreDataMemberAttribute

【讨论】:

  • 谢谢,但它似乎忽略了整个数据成员,即它也不会反序列化它。
猜你喜欢
  • 1970-01-01
  • 2015-09-11
  • 1970-01-01
  • 2023-04-07
  • 1970-01-01
  • 1970-01-01
  • 2014-02-01
  • 2013-07-14
  • 1970-01-01
相关资源
最近更新 更多