Some time ago I created a business logic framework for developing .net applications at my company. It implemented a Data Transfer Object pattern where objects inherited from a base Data Object class where passed through all the application tiers and where ultimately served to UI through a Web Services layer.
Yesterday, a developer came up with a new requirement. He needed to hide a public property of the base data object from serialization at the web service layer and only serialize the attributes he added in the child classes.
One solution to this problem would be to implement the IXmlSerializable interface and provide it’s own serialization code in ReadXml and WriteXml methods, but he didn’t want to have to implement all the serialization in all the classes just to hide a property.
Another solution would be to add the XmlIgnore attribute at the base class property, this way it wouldn’t get serialized by the XmlSerializer, the problem is this would have impact in all the other projects which where using the same library and might rely on this property being serialized.
Since I didn’t want to modify the current interface of the base class to not incur in any compatibility issue with other projects I had to find another way to solve this issue. Finally, I came up with a weird solution which I thought it would be useful to share here 🙂
Let’s suppose that we want to prevent a given property called “State” from serialization. I found out that you can create a new public boolean property called “StateSpecified” (that is, adding the sufix “Specified” to the property name) and if you set that property value to false then the “State” property won’t be serialized. And believe me, it works !
So I finally added the following code at the base class
[XmlIgnore()] public bool StateSpecified = true;
By adding this property, the backward compatibility with any other projects using this base class was assured and the only thing they had to do to hide the property from serialization was to set it’s “XXXSpecified” property to false. The only thing that worries me is that this behaviour isn’t documented or supported by microsoft, it might change in future releases of the .net framework.