I'm refactoring some objects that are serialized to XML but need to keep a few properties for backwards compatibility, I've got a method that converts the old object into the new one for me and nulls the obsolete property. I want to use the Obsolete
attribute to tell other developers not to use this property but it is causing the property to be ignored by the XmlSerializer
.
Similar Code:
[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; } } }
Any ideas on a workaround? My best solution is to write obsolete in the XML comments...
Update: I'm using .NET 2.0
EDIT: After reading a MS Connect article, it appears that .Net 2.0 has a 'feature' where it makes ObsoleteAttribute equivalent to XmlIgnoreAttribute without any notification in the documentation. So I'm going to revise my answer to say that the only way to have your cake and eat it too in this instance is to follow @Will's advice and implement serialization manually. This will be your only future proof way of including Obsolete properties in your XML. It is not pretty in .Net 2.0, but .Net 3.0+ can make life easier.
From XmlSerializer:
Objects marked with the Obsolete Attribute no longer serialized In the .NET Framework 3.5 the XmlSerializer class no longer serializes objects that are marked as [Obsolete].
Another workaround is to subscribe to XmlSerializer.UnknownElement, when creating the serializer for the datatype, and then fix old data that way.
http://weblogs.asp.net/psteele/archive/2011/01/31/xml-serialization-and-the-obsolete-attribute.aspx
Maybe consider to have the method for subscribing as a static method on the class for datatype.
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}); } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With