如果为null或为空,如何忽略序列化中的可空属性?

时间:2013-04-23 14:54:15

标签: c# asp.net xml serialization

我有一个用于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;
        }

5 个答案:

答案 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   实践。只有在有特殊需要时才应该这样做   (例如,为了互操作性或减少数据大小)。

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