【发布时间】:2013-08-28 21:25:07
【问题描述】:
Microsoft XmlSerializer 中似乎存在错误/不一致:如果您的属性标记为 System.ComponentModel.DefaultValue 属性,则不会序列化。很公平 - 这可以被视为一种预期的行为。
问题是反序列化时不尊重相同的属性。下面的代码说明了这个问题。
问题是我怎样才能绕过这个?我可能有数百个业务类在 UI 层(视图)中使用了默认值,因此构造函数中的默认值初始化不是一个选项。它必须是通用的。我可以创建一个全新的默认属性,但这似乎是重复的工作。您是否看到了覆盖 XmlSerializer 行为的方法,或者我应该只使用另一个可以更好地完成工作的序列化程序?
示例代码:
public class DefaultValueTestClass
{
[System.ComponentModel.DefaultValue(10000)]
public int Foo { get; set; }
}
[TestMethod]
public void SimpleDefaultValueTest()
{
// Create object and set the property value TO THE DEFAULT
var before = new DefaultValueTestClass();
before.Foo = 10000;
// Serialize => xml
var serializer = new System.Xml.Serialization.XmlSerializer(typeof(DefaultValueTestClass));
string xml;
using (var stream = new System.IO.StringWriter())
{
serializer.Serialize(stream, before);
xml = stream.ToString();
}
// Deserialize the same object
DefaultValueTestClass after;
using (var reader = new System.IO.StringReader(xml))
{
after = (DefaultValueTestClass)serializer.Deserialize(reader);
}
// before.Foo = 10000
// after.Foo = 0
Assert.AreEqual(before.Foo, after.Foo);
}
【问题讨论】:
-
我猜你可以通过反射,在反序列化时,使用 DefaultValue 属性获取你的类及其超类的所有属性,为每个属性获取值,将其转换为正确的类型,然后仍然通过反射,在你的反序列化对象上调用属性的setter方法,并将抓取的值作为参数
-
@jbl 是的,这就是我在 UI 层所做的。但是我不能在 XmlSerializer.Deserialize 之后这样做,因为我不知道 Foo=0 是因为它没有被序列化还是因为它被用户设置为 0。这样,我需要在反序列化之前插入序列化程序发生。并且不知道如何(除了在构造函数中,由于课程数量众多,我不想这样做)。
-
也许这可以通过一些动态代理来完成,这些代理将实现 IXmlSerializable 接口来代替您的类。我必须承认这只是随机的想法......
标签: c# serialization xmlserializer