I have a class which is used for Xml Serialization.
Inside which I have a nullable property which is decorated with XmlAttribute:
[XmlAttribute("lastUpdated")]
public DateTime? LastUpdated { get; set; }
How to ignore the property from serialization if it is null or empty?
I've tried the below but it doesn't serialize when there is a value (always ignores):
[XmlIgnore]
public DateTime? LastUpdatedValue { get; set; }
[XmlAttribute("lastUpdated")]
public DateTime LastUpdated { get; set; }
public bool ShouldSerializeLastUpdated()
{
return LastUpdatedValue.HasValue;
}
Nullable is not directly supported by XmlSerialization.
If you want use a nullable property you must use a non nullable property and add a boolean property with the same name of property with the suffix "Specified" which specifie when the property must be serializable.
An example with your case :
private DateTime? _lastUpdated;
[XmlAttribute("lastUpdated")]
public DateTime LastUpdated {
get {
return (DateTime)_lastUpdated;
}
set
{
_lastUpdated = value;
}
}
public bool LastUpdatedSpecified
{
get
{
return _lastUpdated.HasValue;
}
}
I know this topic is old. This is the solution I came with. A class which encapsulates the type, and has implicit casting to the type. When serializing, the member variable can be marked with IsNullable = false without getting compiler errors, and blocking it from being serialized when null.
public class Optional<T> where T : struct, IComparable
{
public Optional(T valueObject)
{
Value = valueObject;
}
public Optional()
{
}
[XmlText]
public T Value { get; set; }
public static implicit operator T(Optional<T> objectToCast)
{
return objectToCast.Value;
}
public static implicit operator Optional<T>(T objectToCast)
{
return new Optional<T>(objectToCast);
}
}
Then use it in your class
[Serializable]
[XmlRoot(ElementName = "foo")]
public class foo
{
[XmlElement(ElementName = "myInteger", isNullable = false)]
Optional<int> myInt;
}
You can do things like
myFoo.myInt = 7;
int j = 8 + myFoo.myInt;
For all purposes it's an int. For serialization purposes, it can be null and blocked from being serialized.
This is working for me.
[XmlIgnore]
public float? Speed { get; set; }
[XmlAttribute("Speed")]
public float SpeedSerializable
{
get
{
return this.Speed.Value;
}
set { this.Speed = value; }
}
public bool ShouldSerializeSpeedSerializable()
{
return Speed.HasValue;
}
You can use XmlElementAttribute.IsNullable:
[Serializable]
public class Result
{
[XmlElement(IsNullable = true)]
public DateTime? LastUpdated { get; set; }
}
Note: This works for sure in SOAP contracts in WCF. I haven't tested in other Xml serialization scenarios.
When using a [DataContract]
you can use
[DataMember(EmitDefaultValue = false)]
- For a
boolean
it will only emit the value if it is true
.
- For a
nullable boolean
it will only emit if it is not null
.
- For a
string
it will only emit the value if it isn't null
.
- For an
int
it will only emit the value if it isn't 0
.
etc.
Make sure to put [DataContract]
on the class itself and [DataMember]
on all members you want serialized, whether you're specifying EmitDefaultValue
or not.
Setting the EmitDefaultValue property to false is not a recommended
practice. It should only be done if there is a specific need to do so
(such as for interoperability or to reduce data size).
https://msdn.microsoft.com/en-us/library/system.runtime.serialization.datamemberattribute.emitdefaultvalue(v=vs.110).aspx