4

这是一个关于一般序列化的问题,但特别是我在我的 .NET 代码中使用了ServiceStack 的优秀序列化程序。

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

[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 是一个空列表而不是一个空引用。在我看来,空引用是对象状态的一部分,就像任何实际引用一样。我是对还是错?

4

1 回答 1

4

这是设计使然。

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

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

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

It doesn't work in JSV-Format (i.e. TypeSerializer) which doesn't support null values, since it can't distinguish it from a "null" string literal. So if you want to use the JSV TypeSerializer you should assume null means the default property values of the type (i.e. as specified in the default constructor).

于 2012-08-02T18:08:21.633 回答