过时的属性导致属性被XmlSerialization忽略
我正在重构序列化为XML的一些对象,但需要保留一些属性的向后兼容性,我有一个方法,将旧对象转换为新的对象,并删除过时的属性。 我想使用Obsolete
属性来告诉其他的开发者不要使用这个属性,但是这个属性被XmlSerializer
忽略。
类似代码:
[Serializable] public class MySerializableObject { private MyObject _oldObject; private MyObject _anotherOldObject; private MyObject _newBetterObject; [Obsolete("Use new properties in NewBetterObject to prevent duplication")] public MyObject OldObject { get { return _oldObject; } set { _oldObject = value; } } [Obsolete("Use new properties in NewBetterObject to prevent duplication")] public MyObject AnotherOldObject { get { return _anotherOldObject; } set { _anotherOldObject = value; } } public MyObject NewBetterObject { get { return _anotherOldObject; } set { _anotherOldObject = value; } } }
任何想法在解决方法? 我最好的解决scheme是在XML注释中写入过时
更新:我正在使用.NET 2.0
编辑 : 在阅读MS Connect文章后 ,它似乎.Net 2.0有一个'function',它使ObsoleteAttribute相当于XmlIgnoreAttribute没有任何通知在文档中。 所以我要修改我的答案,说在这种情况下唯一的办法就是吃点蛋糕,然后按照Will的build议, 手动实现序列化 。 这将是您在XML中包含Obsolete属性的唯一未来certificate方式。 在.Net 2.0中并不漂亮,但是.Net 3.0+可以使生活更轻松。
从XmlSerializer :
标有Obsolete属性的对象不再被序列化在.NET Framework 3.5中,XmlSerializer类不再对标记为[Obsolete]的对象进行序列化。
另一个解决方法是订阅XmlSerializer.UnknownElement,为数据types创build序列化程序,然后修复旧数据。
http://weblogs.asp.net/psteele/archive/2011/01/31/xml-serialization-and-the-obsolete-attribute.aspx
也许考虑把订阅的方法作为数据types的类的静态方法。
static void serializer_UnknownElement(object sender, XmlElementEventArgs e) { if( e.Element.Name != "Hobbies") { return; } var target = (MyData) e.ObjectBeingDeserialized; foreach(XmlElement hobby in e.Element.ChildNodes) { target.Hobbies.Add(hobby.InnerText); target.HobbyData.Add(new Hobby{Name = hobby.InnerText}); } }
1)WAG:尝试添加XmlAttributeAttribute属性; 也许这将覆盖ObsoleteAttribute
2)PITA:实现IXmlSerializable
我一直在苦苦挣扎,除了手动序列化或使用其他序列化器之外,没有任何解决scheme。
但是,不要为每个过时的属性编写快速变化的代码,而应该考虑为属性名称添加一个Obsolete
前缀(例如, Foo
变成ObsoleteFoo
,这不会像属性那样生成编译器警告,但至less它是可见的码。
您可以尝试以下解决方法:
添加一个名为的方法
ShouldSerializeOldObject () { return true; } ShouldSerializeAnotherOldObject () { return true }
这可能会覆盖过时的属性
是的,我同意用“Ensole”这个名称来标记“Obsolete”这个名字
/// <summary> /// Determines the swap file location for a cluster. /// </summary> /// <remarks>This enum contains the original text based values for backwards compatibility with versions previous to "8.1".</remarks> public enum VMwareClusterSwapFileLocation { /// <summary> /// The swap file location is unknown. /// </summary> Unknown = 0, /// <summary> /// The swap file is stored in the virtual machine directory. /// </summary> VmDirectory = 1, /// <summary> /// The swap file is stored in the datastore specified by the host. /// </summary> HostLocal = 2, /// <summary> /// The swap file is stored in the virtual machine directory. This value is obsolete and used for backwards compatibility. /// </summary> [XmlElement("vmDirectory")] ObseleteVmDirectory = 3, /// <summary> /// The swap file is stored in the datastore specified by the host. This value is obsolete and used for backwards compatibility. /// </summary> [XmlElement("hostLocal")] ObseleteHostLocal = 4, }