JohnG
JohnG

Reputation: 51

JsonConvert.DeserializeObject boolean always false

Why does the code below returns false for showStatusbar?

I'm trying to use JsonConvert.DeserializeObject to convert a Json file.

using Newtonsoft.Json;
using System;
using System.Collections.Generic;

namespace test
{
    class Program
    {
        static void Main(string[] args)
        {
            string jsonData = "{\"Settings\": [{\"networkDeviceDiscovery\": \"supported\"},{\"showStatusbar\":true}]}";

            Root myDeserializedClass = JsonConvert.DeserializeObject<Root>(jsonData);

            Console.WriteLine("NetworkDeviceDiscovery: {0}", myDeserializedClass.Settings[0].NetworkDeviceDiscovery);
            Console.WriteLine("ShowStatusbar: {0}", myDeserializedClass.Settings[0].ShowStatusbar);
        }
    }

    public class Setting
    {
        [JsonProperty("networkDeviceDiscovery")]
        public string NetworkDeviceDiscovery;

        [JsonProperty("showStatusbar")]
        public bool ShowStatusbar;
    }

    public class Root
    {
        [JsonProperty("Settings")]
        public List<Setting> Settings;
    }
}

Upvotes: 0

Views: 3535

Answers (2)

Xerillio
Xerillio

Reputation: 5259

To make sure we're on the same page, this is the JSON you're dealing with:

{
  "Settings": [
    {
      "networkDeviceDiscovery": "supported"
    },
    {
      "showStatusbar": true
    }
  ]
}

As you can see there are two separate objects which means the two properties networkDeviceDiscovery and showStatusbar only appear in one each. See this fiddle for a demonstration.

Without having more information about the origin of that JSON, what I can suggest is to adjust your Setting class to make all properties nullable, so that you can identify when a property is actually appearing in the JSON or not:

public class Setting
{
    [JsonProperty("networkDeviceDiscovery")]
    public string NetworkDeviceDiscovery;

    [JsonProperty("showStatusbar")]
    public bool? ShowStatusbar;
}

Now, when deserializing the properties are null whenever they don't appear in the JSON. See this fiddle. This makes it easier now for you to combine the list of Settings into one Setting object:

// ...
Root myDeserializedClass = JsonConvert.DeserializeObject<Root>(jsonData);

var resultSettings = new Setting();
foreach (var setting in myDeserializedClass.Settings)
{
    if (setting.ShowStatusbar.HasValue)
    {
        resultSettings.ShowStatusbar = setting.ShowStatusbar;
    }
    // Continue with the other properties...
}

See this final fiddle.

Yes, this is very tedious if there are a lot of properties, but I don't see a much better solution. You could make it more scalable using reflection if you want to dig into that.

Note: I cannot guarantee this solution is in line with the thoughts behind whoever created that API. But as @Selvin mentions, it's probably due to a bad design of the JSON model.

Upvotes: 1

moholy
moholy

Reputation: 26

I think you got the braces wrong. Try this:

string jsonData = "{\"Settings\": [{\"networkDeviceDiscovery\": \"supported\",\"showStatusbar\":true}]}";

Upvotes: 1

Related Questions