Home > Software engineering >  Case insensitive access of JSON keys
Case insensitive access of JSON keys

Time:01-18

I am trying to update json(depth > 2) file using Newtonsoft library. While reading the file, if json keys case are not same as in json file, it failed to fetch its value.

Sample JSON file:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Error",
      "Microsoft.Hosting": "Error"
    }
  },
}

Sample C# Code:

                using (file)
            {
                var serializer = new JsonSerializer();
                var json = null;
                using (var streamReader = new StreamReader(file))
                {
                    using (var reader = new JsonTextReader(streamReader))
                    {
                        try
                        {
                            json = serializer.Deserialize(reader) as JObject;
                        }
                        catch (Exception e)
                        {

                        }
                    }
                }

Now, I am trying to access keys following way:

json["Logging"]["LogLevel"]["microsoft"] 

However, it failed to fetch as 'microsoft' key is in lower case i.e. different case as in json file. I tried searching on web but results shows Newtonsoft lib is by default case-insensitive. However, It doesn't seem to be working in my case. Am I missing syntax to access keys? Please suggest.

CodePudding user response:

The deserializer is case insensitive by default. See this example :

var text = """
    { "sOmEthIng": "Hi, world!" }
    """;

Console.WriteLine(JsonConvert.DeserializeObject<Foo>(text).SoMetHing);

class Foo
{
    public string SoMetHing { get; set; }
}

But in your case, you use Newtonsoft.Json.Linq... where some method are case sensitive. For example, JObject.this[string propertyName] :

public JToken? this[string propertyName]
{
    get
    {
        JProperty? property = Property(propertyName, StringComparison.Ordinal);
        return property?.Value;
    }
}

This explicitly use StringComparison.Ordinal that is case sensitive.


A alternative, it's to use a method that you case specify the case sensibility, like JObject.Property :

var text = """"
        {
      "Logging": {
        "LogLevel": {
          "Default": "Information",
          "Microsoft": "Error",
          "Microsoft.Hosting": "Error"
        }
      },
    }
    """";

var root = JsonConvert.DeserializeObject(text) as JObject;

var logging = root.Property("logging", StringComparison.InvariantCultureIgnoreCase).Value as JObject;
var logLevel = logging.Property("loglevel", StringComparison.InvariantCultureIgnoreCase).Value as JObject;
var microsoft = (logLevel.Property("microsoft", StringComparison.InvariantCultureIgnoreCase).Value as JValue).Value as string;

Console.WriteLine(microsoft);
  • Related