忽略空值-序列化

本文关键字:序列化 空值 | 更新日期: 2023-09-27 18:09:20

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

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

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

忽略空值-序列化

使用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>

据我所知,您可以使用指定功能

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(); } }

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

当使用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接口,以类似的方式自定义输出。