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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16172581/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 00:15:59  来源:igfitidea点击:

How to ignore a nullable property from serialization if it is null or empty?

c#asp.netxmlserialization

提问by The Light

I have a class which is used for Xml Serialization.

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

Inside which I have a nullable property which is decorated with XmlAttribute:

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

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

How to ignore the property from serialization if it is null or empty?

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

I've tried the below but it doesn't serialize when there is a value (always ignores):

我已经尝试了下面的但是当有一个值时它不会序列化(总是忽略):

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

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

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

回答by binard

Nullable is not directly supported by XmlSerialization.

XmlSerialization 不直接支持 Nullable。

If you want use a nullable property you must use a non nullable property and add a boolean property with the same name of property with the suffix "Specified" which specifie when the property must be serializable.

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

An example with your case :

你的情况的一个例子:

    private DateTime? _lastUpdated;

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

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

回答by Yochai Timmer

You can use XmlElementAttribute.IsNullable:

您可以使用XmlElementAttribute.IsNullable

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

回答by DDRider62

I know this topic is old. This is the solution I came with. A class which encapsulates the type, and has implicit casting to the type. When serializing, the member variable can be marked with IsNullable = falsewithout getting compiler errors, and blocking it from being serialized when null.

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

Then use it in your class

然后在你的课堂上使用它

[Serializable]
[XmlRoot(ElementName = "foo")]
public class foo
{
   [XmlElement(ElementName = "myInteger", isNullable = false)]
   Optional<int> myInt;
}

You can do things like

你可以做这样的事情

        myFoo.myInt = 7;
        int j = 8 + myFoo.myInt;

For all purposes it's an int. For serialization purposes, it can be null and blocked from being serialized.

出于所有目的,它是一个整数。出于序列化目的,它可以为空并阻止被序列化。

回答by Madhu Nadamala

This is working for me.

这对我有用。

    [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;
    }

回答by Simon_Weaver

Note: This works for sure in SOAP contracts in WCF. I haven't tested in other Xml serialization scenarios.

注意:这在 WCF 中的 SOAP 契约中肯定有效。我还没有在其他 Xml 序列化场景中测试过。

When using a [DataContract]you can use

使用时,[DataContract]您可以使用

[DataMember(EmitDefaultValue = false)]

[DataMember(EmitDefaultValue = false)]

  • For a booleanit will only emit the value if it is true.
  • For a nullable booleanit will only emit if it is not null.
  • For a stringit will only emit the value if it isn't null.
  • For an intit will only emit the value if it isn't 0.
  • 对于 a boolean,如果它是 ,它只会发出值true
  • 对于 anullable boolean它只会在它不是 时发出null
  • 对于 astring它只会发出值,如果它不是null
  • 对于 an ,int它只会在它不是 时发出值0

etc.

等等。

Make sure to put [DataContract]on the class itself and [DataMember]on all members you want serialized, whether you're specifying EmitDefaultValueor not.

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

Setting the EmitDefaultValue property to false is not a recommended practice. It should only be done if there is a specific need to do so (such as for interoperability or to reduce data size).

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

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

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