【问题标题】:How to ignore a nullable property from serialization if it is null or empty?如果它为空或为空,如何从序列化中忽略可为空的属性?
【发布时间】:2013-04-16 20:36:11
【问题描述】:

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

【问题讨论】:

  • 您希望 XML 是什么样子?在这种情况下,如果属性为 null,您将获得 <lastUpdated xsi:nil="true"/>;您可以对 xml 进行后处理(更容易),也可以编写一个 XmlWriter 类(更难,性能更好)。还有其他一些选项既困难又使您的代码膨胀。
  • 不,如果 xmlattribute 为空,我只想忽略它。但是日期时间?不可序列化。怎么换?

标签: c# asp.net xml serialization


【解决方案1】:

XmlSerialization 不直接支持 Nullable。

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

你的例子:

    private DateTime? _lastUpdated;

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

    public bool LastUpdatedSpecified
    {
        get
        {
            return _lastUpdated.HasValue;
        }
    }

【讨论】:

  • 谢谢,但问题是我无法再使用 XmlSerializer 对其进行序列化。我收到了这个错误:+ InnerException {“有一个错误反映属性'LastUpdated'。”} System.Exception {System.InvalidOperationException}
  • 对不起,我太快了,我更正并编辑了我的代码。你可以试试这个吗?
  • @TheLight 你能接受我的回答,比如最佳回复吗?
  • 如果_lastUpdated 没有值,return (DateTime)_lastUpdated; 将抛出InvalidOperationException
  • LastUpdatedSpecified 用在哪里?
【解决方案2】:

我知道这个话题很老了。这是我带来的解决方案。封装类型的类,并隐式转换为类型。序列化时,成员变量可以用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 并阻止被序列化。

【讨论】:

  • 谢谢,这对我来说很好用!当将它与另一个自定义数据类型一起使用时(我的布尔值需要序列化为 Y/N),我已将 IComparable 更改为 IComparable,我可以在我的 CustomBool 类型中实现 IComparable
  • 这不适用于 [XmlElement(DataType="date")]。 “日期”是 XmlElementAttribute.DataType 属性的无效值。该属性只能为原始类型指定。
【解决方案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;
    }

【讨论】:

    【解决方案4】:

    您可以使用XmlElementAttribute.IsNullable

    [Serializable]
    public class Result
    {
        [XmlElement(IsNullable = true)]
        public DateTime? LastUpdated  { get; set; }
    }
    

    【讨论】:

    • 它不能与属性一起使用。它仅用于元素。
    【解决方案5】:

    注意:这肯定适用于 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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-09-09
      • 2021-08-09
      • 2011-09-24
      • 1970-01-01
      • 2017-08-08
      • 2021-01-03
      • 2016-05-17
      • 2015-12-14
      相关资源
      最近更新 更多