这是一个关于序列化的一般问题,但特别是我使用的是 ServiceStack's excellent serializers在我的 .NET 代码中。
反序列化器是否应该在属性上设置空引用?目前似乎它忽略了空引用,只允许根据类的默认值设置此类字段。例如,此测试失败:
[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 是一个空列表而不是一个空引用。在我看来,空引用就像任何实际引用一样是对象状态的一部分。我是对还是错?
最佳答案
这是设计使然。
默认情况下(为了节省带宽)ServiceStack 的文本序列化器不发出 null
线上的值(value)。如果没有 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; }
}
它不适用于不支持
null
的 JSV 格式(即 TypeSerializer )值,因为它无法将其与 "null"
区分开来字符串字面量。所以如果你想使用 JSV TypeSerializer 你应该假设 null
表示类型的默认属性值(即在默认构造函数中指定)。
关于.net - 反序列化和空引用最佳实践 - 设置为空还是忽略?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11782042/