2

My objects has a parent-child relationship. Each child object has a Parent property pointing to its container. When this object is created in the app, it's set, and thus no problem. This Parent property is marked with XmlIgnore attribute, because it needs to be set to its run-time parent instance. So, what's the best way to initialize this Parent property after the object is deserialized? Is there a 'Deserialize completed' event or something similar?

EDIT: I'm talking about XmlSerializer in C# WPF. I don't want binary serializer.

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
newman
  • 6,841
  • 21
  • 79
  • 126

2 Answers2

1

XmlSerializer does not provide serialization callbacks, I'm afraid. One way to do this is for the parent to handle this when adding - but you will need a custom collection (perhaps inherited from Collection<T>) that during Add/Remove calls some method on the child to add (or remove, if removing from the collection) the parent.

Alternatively - consider simply making it a one-way only tree - i.e. the child doesn't have a parent property.

Another option is simply to walk the model through code after deserialization, and fixup any parent values.

The final option is to implement IXmlSerializable, but that is very hard get right.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • Thanks for your input. "Another option is simply to walk the model through code after deserialization, and fixup any parent values". Yeah, this is the approach I'm currently use and I'm not satisfied with it because I have a lot of objects to serialize. – newman Nov 13 '10 at 14:08
  • A comment on "Alternatively - consider simply making it a one-way only tree - i.e. the child doesn't have a parent property". In fact, in another project I'm working on is taking this approach - I'm not sure if it's due to serialization issue. I feel this approach has a major defect that an object is no more an "object", but mere a data structure because without parent it doesn't know what to do in many cases. – newman Nov 13 '10 at 15:25
1

Your question is somewhat lacking in details, but from some of the attributes and properties that you describe, I'm going to assume that you're using the XMLSerializer in the .NET Framework.

You may know about the OnDeserialized attribute, which you can use to mark a particular method that you want to be called after an object has been deserialized. Unfortunately, this only works with the Binary, SOAP, and DataAttribute formatters, not for XMLSerializer.

In order to achieve this same functionality using the XMLSerializer, you will have to implement the IXmlSerializable interface yourself on the class that you want to serialize to XML. This will allow you to complete control over how instances of your class are serialized and deserialized, including code that is run to initialize the Parent property after an object is deserialized.

There is a good example article on CodeProject that describes how to correctly implement IXmlSerializable available here.

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
  • I was looking for OnDeserialized attribute I had used a few years back, but I forgot it was for binary serialization only. I guess I have to look into implementing IXmlSerializable because I have a lot of objects to serialize. Thank you very much for your answer. – newman Nov 13 '10 at 14:36
  • Okay, I just took a look at the CodeProject article. I don't think I'll take that approach. Not only because I have a lot of objects to serialize, but also I don't have any problem with the serialization itself. The only missing thing is an event after the object gets deserialized. I'm looking for a simple, easier solution. I'm wondering why Microsoft decided not to implement OnDeserialized attribute for XmlSerializer. Any explanation? – newman Nov 13 '10 at 15:15
  • Microsoft decided to make XML (which of course includes XML serialization) a completely separate piece of the framework. I guess that's the explanation, but I'm not sure if that helps. If it were me, I'd probably punt and figure out a way to use binary serialization. Perhaps you could also look into inheriting off of `XMLSerializer` and raising your own callback event in an overridden `Deserialize` method. I'm afraid there's just no simple or easy way to do this. – Cody Gray - on strike Nov 13 '10 at 15:36
  • Binary serialization is not an option for me. I just looked at your suggestion to inherit XmlSerializer, but realize this extra work is not much better than my current approach (call a function after deserialize to fix it up). Thanks very much for your thoughts! – newman Nov 13 '10 at 17:30