如果为null或为空,如何忽略序列化中的可空属性?
我有一个用于Xml序列化的类。
在其中我有一个可以使用XmlAttribute修饰的可空属性:
[XmlAttribute("lastUpdated")] public DateTime? LastUpdated { get; set; }
如果属性为null或为空,如何忽略序列化的属性?
我已经尝试过以下但是当有值时它不会序列化(总是忽略):
[XmlIgnore] public DateTime? LastUpdatedValue { get; set; } [XmlAttribute("lastUpdated")] public DateTime LastUpdated { get; set; } public bool ShouldSerializeLastUpdated() { return LastUpdatedValue.HasValue; }
XmlSerialization不直接支持Nullable。
如果要使用可空属性,则必须使用非可空属性,并添加具有相同名称的属性的布尔属性,后缀为“已指定”,该属性指定属性何时必须可序列化。
您的案例的一个例子:
private DateTime? _lastUpdated; [XmlAttribute("lastUpdated")] public DateTime LastUpdated { get { return (DateTime)_lastUpdated; } set { _lastUpdated = value; } } public bool LastUpdatedSpecified { get { return _lastUpdated.HasValue; } }
我知道这个话题很老。 这是我带来的解决方案。 封装类型的类,并对类型进行隐式转换。 序列化时,可以使用IsNullable = false标记成员变量,而不会出现编译器错误,并阻止它在null时序列化。
public class Optional where T : struct, IComparable { public Optional(T valueObject) { Value = valueObject; } public Optional() { } [XmlText] public T Value { get; set; } public static implicit operator T(Optional objectToCast) { return objectToCast.Value; } public static implicit operator Optional (T objectToCast) { return new Optional (objectToCast); } }
然后在课堂上使用它
[Serializable] [XmlRoot(ElementName = "foo")] public class foo { [XmlElement(ElementName = "myInteger", isNullable = false)] Optional myInt; }
你可以做的事情
myFoo.myInt = 7; int j = 8 + myFoo.myInt;
出于所有目的,它是一个int。 出于序列化目的,它可以为null并阻止序列化。
您可以使用XmlElementAttribute.IsNullable :
[Serializable] public class Result { [XmlElement(IsNullable = true)] public DateTime? LastUpdated { get; set; } }
这对我有用。
[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; }
注意:这在WCF中的SOAP合同中肯定有效。 我没有在其他Xml序列化方案中测试过。
使用[DataContract]
时可以使用
[DataMember(EmitDefaultValue = false)]
- 对于
boolean
它只会在值为true
发出值。 - 对于可以为
nullable boolean
,只有在它不为null
才会发出。 - 对于
string
,如果它不为null
,它将仅发出值。 - 对于
int
,如果它不是0
,它将仅发出值。
等等
无论您是否指定EmitDefaultValue
,请确保将[DataContract]
放在类本身上,并将[DataMember]
放在要序列化的所有成员上。
建议不要将EmitDefaultValue属性设置为false。 只有在特定需要时才应该这样做(例如,为了互操作性或减少数据大小)。