5

我有一个用于 Xml 序列化的类。

在其中我有一个用 XmlAttribute 装饰的可为空的属性:

 [XmlAttribute("lastUpdated")]
 public DateTime? LastUpdated { get; set; }

如果属性为空或为空,如何从序列化中忽略该属性?

我已经尝试过以下方法,但是当有值时它不会序列化(总是忽略):

  [XmlIgnore]
        public DateTime? LastUpdatedValue { get; set; }

        [XmlAttribute("lastUpdated")]
       public DateTime LastUpdated { get; set; }

        public bool ShouldSerializeLastUpdated()
        {
            return LastUpdatedValue.HasValue;
        }
4

5 回答 5

11

XmlSerialization 不直接支持 Nullable。

如果要使用可为空的属性,则必须使用不可为空的属性并添加一个与属性同名的布尔属性,后缀为“指定”,指定何时该属性必须是可序列化的。

您的案例示例:

    private DateTime? _lastUpdated;

    [XmlAttribute("lastUpdated")]
    public DateTime LastUpdated {
        get {
            return (DateTime)_lastUpdated;
        }
        set
        {
            _lastUpdated = value;
        }
    }

    public bool LastUpdatedSpecified
    {
        get
        {
            return _lastUpdated.HasValue;
        }
    }
于 2013-04-23T15:40:08.180 回答
5

我知道这个话题很老了。这是我带来的解决方案。封装类型的类,并隐式转换为类型。序列化时,成员变量可以用IsNullable = false标记,不会出现编译器错误,并且在为空时阻止它被序列化。

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 并阻止被序列化。

于 2016-06-03T17:58:13.363 回答
4

这对我有用。

    [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;
    }
于 2016-07-29T06:15:29.040 回答
2

您可以使用XmlElementAttribute.IsNullable

[Serializable]
public class Result
{
    [XmlElement(IsNullable = true)]
    public DateTime? LastUpdated  { get; set; }
}
于 2013-12-18T08:02:51.717 回答
2

注意:这肯定适用于 WCF 中的 SOAP 合同。我没有在其他 Xml 序列化场景中测试过。

使用[DataContract]时可以使用

[DataMember(EmitDefaultValue = false)]

  • 对于 aboolean它只会在它是 时发出值true
  • 对于 anullable boolean它只有在不是 时才会发出null
  • 对于 astring它只会在不是时发出值null
  • 对于 anint它只会在不是时发出值0

等等

确保将[DataContract]类本身和[DataMember]您想要序列化的所有成员都放在上面,无论您是否指定EmitDefaultValue

不建议将 EmitDefaultValue 属性设置为 false。只有在有特殊需要时才应该这样做(例如为了互操作性或减少数据大小)。

https://msdn.microsoft.com/en-us/library/system.runtime.serialization.datamemberattribute.emitdefaultvalue(v=vs.110).aspx

于 2017-10-25T08:41:30.153 回答