反序列化和空引用最佳实践 - 设置为null或忽略?

时间:2012-08-02 16:40:51

标签: .net serialization servicestack cloning

这是关于序列化的一般问题,但特别是我在.NET代码中使用ServiceStack's excellent serializers

反序列化器是否应该在属性上设置空引用?它似乎目前忽略了空引用,只允许根据类的默认值设置这些字段。例如,此测试失败:

[TestMethod]
public void Deserialize_WithNullCollection_CollectionIsNull() {
    var serializer = new ServiceStack.Text.TypeSerializer<Foo>();
    Foo item = new Foo() { Strings = null };
    Foo result = serializer.DeserializeFromString(serializer.SerializeToString(item));
    Assert.IsNull(result.Strings);
}
public class Foo {
    public Foo() {
        Strings = new List<string>();
    }
    public List<string> Strings { get; set; }
}

我相信也许这个测试应该成功,但它不会--item.Foo是一个空列表而不是空引用。在我看来,空引用是对象状态的一部分,就像任何实际引用一样。我是对还是错?

1 个答案:

答案 0 :(得分:4)

这是设计的。

默认情况下(为了节省带宽)ServiceStack的文本序列化器不会在线路上发出null值。如果生成的JSON中没有null,那么在反序列化时属性不会被设置,这就是它采用构造函数中给出的默认值的原因。

您可以使用以下方法启用空值:

JsConfig.IncludeNullValues = true;

这是一个静态(共享)属性,因此设置一次应该在流程中全局应用。

使用 JsonSerilaizer

时,此测试通过
    [Test]
    public void Deserialize_WithNullCollection_CollectionIsNull()
    {
        JsConfig.IncludeNullValues = true;
        var item = new Foo { Strings = null };
        var json = JsonSerializer.SerializeToString(item);
        var result = JsonSerializer.DeserializeFromString<Foo>(json);
        Assert.IsNull(result.Strings);
    }

    public class Foo
    {
        public Foo()
        {
            Strings = new List<string>();
        }
        public List<string> Strings { get; set; }
    }

它不能用于JSV格式(即 TypeSerializer ),它不支持null值,因为它无法将其与"null"字符串区分开来文字。因此,如果您想使用JSV TypeSerializer,您应该假设null表示该类型的默认属性值(即在默认构造函数中指定)。