JSON serializer doesn't output "false"

I have a DTO which includes a boolean like this:

public bool DirectMember { get; set; }

When the property is true it is outputted with the JSON. However when it’s false the property is omitted in the serialized JSON.

I guess this is an optimization, as most deserializers will set the boolean on the receiver end to false, at least if they know the shape of the object, however shouldn’t it be possible to output the false if one would like to?

I suspect many developers don’t always look at docs, but just at the output, and then having the value there, even though it’s false, provides some insight.

In the DTO I’ve tried this:

    [DataMember(EmitDefaultValue = true)]
    public bool DirectMember { get; set; }

and in Configure.AppHost.cs I have set:

        JsConfig.Init(new ServiceStack.Text.Config
        {
            DateHandler = DateHandler.ISO8601,
            AlwaysUseUtc = false,
            TextCase = TextCase.CamelCase,
            ExcludeDefaultValues = false,        
            IncludeNullValues = true
        });

But still I don’t get the property serialized if the value is false.

It’s controlled by ExcludeDefaultValues, which since you’re not excluding them should be included.

class A
{
    public bool DirectMember { get; set; }
}


JsConfig.Init(new ServiceStack.Text.Config
{
    DateHandler = DateHandler.ISO8601,
    AlwaysUseUtc = false,
    TextCase = TextCase.CamelCase,
    ExcludeDefaultValues = false,        
    IncludeNullValues = true
});

var a = new A();
a.ToJson().Print();

Which prints out:

{"directMember":false}

Thanks for answering so quickly.

I’ve setup a demo, in which you can see that the “false” doesn’t output.
Test with empty “name” in Hello, or non-empty name for true.

Works for me:

Yes, you’re right, it works on that URL.

It must be the UI, see the screenshot. Seems it sends its own jsconfig parameter. That’s a bit confusing, the API explorer is one case where I’d definitly like to see all parameters, as it’s about exploring what’s there. Ideally it should override to show null + false, whereas in production I’d more likely remove these parameters.

Due to all the possible configurations of JSON output, the API Explorer and other UIs need to send their own JSON configuration that controls the payload options to work consistently, and this is currently the same for when using/viewing responses in the UIs. It’s a trade off, having it work differently in prod/dev could also cause issues depending on your testing/release workflows, but I understand where the confusion has happened. The Details and Code tab should reflect the payload information correctly since they are based off your DTOs.

Appreciate the feedback, and we will look at options for possible improvements in the future when we are next diving into work on the built in UIs.

For clarity the UI excludes default values to only show data the API actually returns as otherwise all value types like dates and numbers will return their empty values, which drowns out real API data with default values. Otherwise queries that return partial data like selecting custom fields from AutoQuery APIs would appear misleading since it returns default values for the columns that should’ve been omitted, instead of not returning any values.

Like @layoric mentions, use Details and Code tab to explore the structure of your APIs. executing the API is for showing actual data APIs return.

Thanks for the explanation of why the UI needs to override my settings for JSON export. It caused a bit of confusion, but now I know.

Regarding the Details View, shouldn’t it include the nested objects? Following the convention of SS, I’m returning a list of objects, but the details of the object is lost (see screenshot).

I know I can find out the details by using the Code View, perhaps it’s just me, but I prefer the Details view, as it is focused on what’s transmitted, not code. I find that a REST API should be language independent, so giving people code examples are fine, but at least the JSON “shape” should be communicated. For example, using JS, I would not use classes like the JS example at all.

I guess the good old metadata path gives me what I need.

The latest v6.11.1+ (now available in pre release packages) should now include more of the referenced types from generic property type args. As this list can get quite large I’ve also made them linkable where the types exist.

1 Like