Question

This is a question about serialization in general, but in particular I am using ServiceStack's excellent serializers in my .NET code.

Should the deserializers set null references on properties? It seems like currently it ignores null references and just allows such fields to be set according the class's defaults. For example, this test fails:

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

I believe this perhaps this test ought to succeed, but it does not--item.Foo is an empty list rather than a null reference. It seems to me that null references are part of an object's state just like any actual reference is. Am I right or wrong?

Was it helpful?

Solution

This is by design.

By default (to save bandwidth) ServiceStack's text serializers don't emit null value on the wire. If there is no null in the generated JSON then the property doesn't get set when its deserialized, which is why it takes the default value given in the constructor.

You can enable null values with:

JsConfig.IncludeNullValues = true;

This is a static (Shared) property, so setting it once should apply globally in the process.

This test passes when using the 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).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top