【问题标题】:Ignore null values - Serialization忽略空值 - 序列化
【发布时间】:2015-11-15 13:13:23
【问题描述】:

如何设置System.Runtime.Serialization 序列化程序以忽略空值?

或者我必须为此使用XmlSerializer 吗?如果有,怎么做?

(我不想写<ecommerceflags i:nil="true"/>这样的标签,如果它为空就跳过它)

【问题讨论】:

  • 你序列化的是什么类型的空?空值?字符串?
  • 空值。可为空的整数、双精度数、小数...

标签: c# xml serialization asp.net-web-api


【解决方案1】:

使用System.Runtime.Serialization.DataContractSerializer,您需要使用[DataMember(EmitDefaultValue = false)] 标记属性。

例如,下面的代码:

class Program
{
    static void Main()
    {
        Console.WriteLine(SerializeToString(new Person { Name = "Alex", Age = 42, NullableId = null }));
    }

    public static string SerializeToString<T>(T instance)
    {
        using (var ms = new MemoryStream())
        {
            var serializer = new DataContractSerializer(typeof(T));
            serializer.WriteObject(ms, instance);
            ms.Seek(0, SeekOrigin.Begin);
            using (var sr = new StreamReader(ms))
            {
                return sr.ReadToEnd();
            }
        }
    }
}

[DataContract]
public class Person
{
    [DataMember]
    public string Name { get; set; }
    [DataMember]
    public int Age { get; set; }
    [DataMember(EmitDefaultValue = false)]
    public int? NullableId { get; set; }
}

打印以下内容:

<Person xmlns="http://schemas.datacontract.org/2004/07/ConsoleApplication4" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
  <Age>42</Age>
  <Name>Alex</Name>
</Person>

【讨论】:

  • 谢谢。这就是我一直在寻找的。最干净、最简单的解决方案。
【解决方案2】:

虽然它的价值较小(除了它使序列化的流更短),但您可以自定义序列化来实现这一点。

使用System.Runtime.Serialization时,可以实现ISerializable接口:

[Serializable]
public class MyClass: ISerializable
{
    private string stringField;
    private object objectField;

    public void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        if (stringField != null)
            info.AddValue("str", stringField);

        if (objectField != null)
            info.AddValue("obj", objectField);
    }

    // the special constructor for deserializing
    private MyClass(SerializationInfo info, StreamingContext context)
    {
        foreach (SerializationEntry entry in info)
        {
            switch (entry.Name)
            {
                case "str":
                    stringField = (string)entry.Value;
                    break;
                case "obj":
                    objectField = entry.Value;
                    break;
            }
        }
    }
}

使用XML序列化时,可以实现IXmlSerializable接口,类似的方式自定义输出。

【讨论】:

    【解决方案3】:

    据我所知,您可以使用 Specified-Feature

    public int? Value { get; set; }
    
    [System.Xml.Serialization.XmlIgnore]
    public bool ValueSpecified { get { return this.Value != null; } }
    

    只有在指定时才写。

    另一种方法是

    [System.Xml.Serialization.XmlIgnore]
    private int? value;
    
    public int Value { get { value.GetValueOrDefault(); } }
    

    【讨论】:

      猜你喜欢
      • 2013-04-11
      • 2020-01-23
      • 2016-11-28
      • 2013-02-17
      • 2019-10-22
      • 2016-08-31
      • 2016-05-17
      • 2017-10-16
      • 1970-01-01
      相关资源
      最近更新 更多