这是关于序列化的一般问题,但特别是我在.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是一个空列表而不是空引用。在我看来,空引用是对象状态的一部分,就像任何实际引用一样。我是对还是错?
答案 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
表示该类型的默认属性值(即在默认构造函数中指定)。