How to force System.Text.Json.JsonElement.GetProperty to search for properties using case-insensitive method?
Asked Answered
A

4

5

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?

Atheling answered 15/12, 2021 at 15:41 Comment(0)
P
4

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())
Primalia answered 15/12, 2021 at 16:0 Comment(0)
L
3

Another option is to use System.Text.json.JsonNode with a JsonNodeOptions:

var jsonNode = JsonNode.Parse(
    "jsonStr", 
    new JsonNodeOptions {PropertyNameCaseInsensitive = true});

jsonNode["FirstName"].ToString(); // this returns 'Somebody'
jsonNode["firStNamE"].ToString(); // this returns 'Somebody'
Leavy answered 12/8, 2022 at 8:11 Comment(0)
A
2

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'
Adlib answered 15/12, 2021 at 19:45 Comment(0)
B
0

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;
Borlase answered 15/12, 2021 at 19:17 Comment(5)
I like this approach due to its simplicityAdlib
@NigelBess Thank you! And you can use all Linq functions for search as well.Borlase
Actually, JsonElement doesnt have the method Properties() learn.microsoft.com/en-us/dotnet/api/…Adlib
@NigelBess What JsonElement has to do with PO json? We are talking how to get a value by name , not about JsonElement.Borlase
Ops question is about JsonElementAdlib

© 2022 - 2024 — McMap. All rights reserved.