I'm trying to find a way to change the serialization behavior of a property.
Lets say I have a situation like this:
[Serializable]
public class Record
{
public DateTime LastUpdated {get; set; }
// other useful properties ...
}
public class EmployeeRecord : Record
{
public string EmployeeName {get; set; }
// other useful properties ...
}
Now I want to serialize EmployeeRecord. I don't want the LastUpdated property from the Record class to be serialized. (I do want LastUpdated to be serialized when I serialize Record, though).
First I tried hiding the LastUpdated property by using the new keyword and then adding the XmlIgnore attribute:
public class EmployeeRecord : Record
{
public string EmployeeName {get; set; }
[XmlIgnore]
public new DateTime LastUpdated {get; set; }
// other useful properties ...
}
But that didn't work. Then I tried making the base LastUpdated virtual and overriding it, keeping the attribute:
[Serializable]
public class Record
{
public virtual DateTime LastUpdated {get; set; }
// other useful properties ...
}
public class EmployeeRecord : Record
{
public string EmployeeName {get; set; }
[XmlIgnore]
public override DateTime LastUpdated {get; set; }
// other useful properties ...
}
This didn't work either. In both attempts the LastUpdated ignored the XmlIgnore attribute and happily went about its business of serializing.
Is there a way to make what I'm trying to do happen?
First, the [Serializable] attr has nothing to do with the XmlSerializer. That is a red herring. [Serializable] is meaningful to System.Runtime.Serialization, while the XmlSerializer lives in System.Xml.Serialization. If you are decorating your class with [Serializable] and your members with [XmlIgnore] then you are probably confusing yourself or other readers of your code.
XmlSerialization in .NET is very flexible. Depending on how the serialization is being done, directly by you or indirectly, let's say by the web services runtime - you have different ways to control things.
One option is to use the propertyNameSpecified pattern to turn ON or OFF the property in XML Serialization. Suppose you have this code:
Then, if LastModifiedSpecified is false in an instance, the LastModified field will not be serialized for that instance. In the constructor for your type, you can set LastModifiedSpecified to always be true in the base type, and always false in the derived type. The actual boolean - LastModifiedSpecified - never gets serialized because it is marked XmlIgnore.
This little trick is documented here.
Your other option is to use XmlAttributeOverrides, which is a way of dynamically providing the set of XML serialization attributes (like XmlElementAttribute, XmlIgnoreAttribute, XmlRootAttribute, and so on...) - dynamically providing those attributes to the serializer at runtime. The XmlSerializer, instead of inspecting the type itself for those attributes, will just walk through the list of override attributes provided to its constructor.
This is illustrated in more detail here.
In your case, you would provide an XmlIgnoreAttribute as an override, but only when serializing the derived type. (or whatever) This works only when you directly instantiate the XmlSerializer - it won't work when serialization is done implicitly by the runtime, as with web services.
Cheers!
The best I can think of...
Basically, there are a few patterns that
XmlSerializer
respects;public bool ShouldSerialize*()
, andpublic bool *Specified {get;set;}
(note you should mark*Specified
with[XmlIgnore]
too...).Not very elegant, I'll grant; but
XmlSerializer
only looks at public members, so you can't even hide them (short of[EditorBrowsable(EditorBrowsableState.Never), Browsable(false)]
).