Home > Software engineering >  How to force System.Text.Json.JsonElement.GetProperty to search for properties using case-insensitiv
How to force System.Text.Json.JsonElement.GetProperty to search for properties using case-insensitiv

Time:12-16

Here's my JSON:

{
    firstName: 'Somebody',
    lastName: 'Else'
}

And I deserialize it into JsonElement using these options:

var options = new JsonSerializerOptions {
                    WriteIndented = true,
                    PropertyNameCaseInsensitive = true,
                    PropertyNamingPolicy = JsonNamingPolicy.CamelCase
                };

But then I want to search for properties, it becomes case-sensitive.

element.GetProperty("FirstName") // this returns null
element.GetProperty("firstName") // this returns 'Somebody'

How can I force GetProperty method to become case-insensitive?

CodePudding user response:

As per the docs you should be able to create JsonNamingPolicy like this one which should do the job:

using System.Text.Json;

namespace SystemTextJsonSamples
{
    public class LowerCaseNamingPolicy : JsonNamingPolicy
    {
        public override string ConvertName(string name) =>
            name.ToLower();
    }
}

EDIT: Then you can use it by changing your options configuration to this:

var options = new JsonSerializerOptions {
    WriteIndented = true,
    PropertyNameCaseInsensitive = true,
    PropertyNamingPolicy = new LowerCaseNamingPolicy()
};

Edit2:

then you can search for the property the following way:

element.GetProperty("FirstName".ToLower())
element.GetProperty("firstName".ToLower())

CodePudding user response:

You can write an extension method for this:

static class JEelementExtensions
{
    public static object GetPropertyCaseInsensitive(this JsonElement element, string propertyName)
    {
        foreach (var property in element.EnumerateObject().OfType<JsonProperty>())
        {
            if (property.Name.Equals(propertyName, StringComparison.OrdinalIgnoreCase)) return property.Value;
        }
        return null;
    }
}

And here is the same extension method as a one-liner. This version throws an exception if the property doesnt exist:

public static object GetPropertyCaseInsensitive(this JsonElement element, string propertyName) => element
    .EnumerateObject().First(p => p.Name.Equals(propertyName, StringComparison.OrdinalIgnoreCase)).Value;

Usage:

    var prop1 = element.GetPropertyCaseInsensitive("firstName");// this returns 'Somebody'
    var prop2 = element.GetPropertyCaseInsensitive("FirstName");// this returns 'Somebody'
    var prop3 = element.GetPropertyCaseInsensitive("fIrStNAmE");// this returns 'Somebody'

CodePudding user response:

you don't need any options, if you use LINQ to JSON of NewtonSoft.Jason

Try this code , assuming jObject = JObject.Parse(json). This code was tested in Visual Studio using your json

 var firstName= jObject.Properties().First(i=>i.Name.ToLower()=="firstname").Value;

using this algoritm you can use not only ==, but Contains, StartWith, EndsEith.

var firstName= jObject.Properties().FirstOrDefault(i=> i.Name.ToLower()
.Contains("first")).Value;
  • Related