4

I'm writing a small C# application that needs to be able to read/write some config data as XML. I'm doing this by creating some simple model classes with properties that have XmlElement attributes where needed, and running the whole thing through an XmlSerializer.

I would like to have the XmlSerializer behave exactly as it usually does, except I want any null properties on serialized objects to be written as empty elements. (Currently it skips them entirely.) And likewise, when deserializing, I'd like it to interpret empty elements as null, rather than as an empty string.

What's the most straight-forward way to achieve this? The suggestions I've seen for similar situations involve using the IsNullable argument for XmlElement, creating ShouldSerialize methods, etc. This has to be done for every property, creating a lot of unnecessary code. In this case, I want it to be universal for anything I'm (de)serializing. If I need to extend XmlSerializer, that's fine, and I could live with implementing IXmlSerializable on the model classes, but I'm not entirely sure where to start with those two possible approaches.

db2
  • 497
  • 1
  • 3
  • 21
  • Could you try this? https://stackoverflow.com/a/306980/2315752 – Nekeniehl Dec 13 '17 at 16:40
  • @Nekeniehl I'd like to avoid having to set `IsNullable` on every property, and use `xsi:nil="true"` on every empty element in the XML file, if possible. – db2 Dec 13 '17 at 16:42
  • I see, you don't have many options left other than the suggestions you already found. Using reflection on the `WriteXml()` to check the property you are serializing, and whenever is null, add it as empty tag. http://www.developerfusion.com/code/4639/customize-xml-serialization-using-ixmlserializable/ Sorry I cannot help you more. – Nekeniehl Dec 13 '17 at 17:01
  • @Nekeniehl Thanks, that might be workable, if I create an abstract base class that implements `IXmlSerializable`, and extend that with any of the model classes I want to inherit this behavior. – db2 Dec 13 '17 at 17:16
  • The only problem I see it will be the performance vs the work to set `IsNullable` and the other suggestions. But if it is not a requirement I wish you luck! – Nekeniehl Dec 13 '17 at 17:21
  • This is not easy to do, and I'm not sure I would recommend it. But one approach is to 1) Use reflection to construct an `XmlSerializer` from `XmlAttributeOverrides` that programmatically sets `[XmlElement(IsNullable = true)]` for all public properties of all types being serialized. [This answer](https://stackoverflow.com/a/28107096/3744182) does something similar. Then 2) subclass `XmlWriter` to omit the `xsi:nil` attribute. See https://dotnetfiddle.net/0e9AWe for a demo of such a writer, and [here](https://stackoverflow.com/a/42960980/3744182) for an example of subclassing `XmlWriter`. – dbc Dec 13 '17 at 18:38

0 Answers0