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