如何强制 System.Text.Json.JsonElement.GetProperty 使用不区分大小写的方法搜索属性?

Posted

技术标签:

【中文标题】如何强制 System.Text.Json.JsonElement.GetProperty 使用不区分大小写的方法搜索属性?【英文标题】:How to force System.Text.Json.JsonElement.GetProperty to search for properties using case-insensitive method? 【发布时间】:2022-01-18 19:15:39 【问题描述】:

这是我的 JSON:


    firstName: 'Somebody',
    lastName: 'Else'

我使用这些选项将其反序列化为JsonElement

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

但后来我想搜索属性,它变成了区分大小写

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

如何强制GetProperty 方法不区分大小写?

【问题讨论】:

【参考方案1】:

根据docs,您应该能够像这样创建JsonNamingPolicy,它应该可以完成这项工作:

using System.Text.Json;

namespace SystemTextJsonSamples

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

编辑: 然后您可以通过将选项配置更改为以下方式来使用它:

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

编辑2:

那么您可以通过以下方式搜索该属性:

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

【讨论】:

【参考方案2】:

你可以为此写一个扩展方法:

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;
    

这里是和单线一样的扩展方法。如果该属性不存在,此版本将引发异常:

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

用法:

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

【讨论】:

【参考方案3】:

如果您使用 NewtonSoft.Jason 的 LINQ to JSON,则不需要任何选项

试试这个代码,假设 jObject = JObject.Parse(json)。此代码已在 Visual Studio 中使用您的 json 进行了测试

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

使用此算法,您不仅可以使用 ==,还可以使用 Contains、StartWith、EndsEith。

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

【讨论】:

我喜欢这种方法,因为它很简单 @NigelBess 谢谢!您也可以使用所有 Linq 函数进行搜索。 其实JsonElement没有Properties()docs.microsoft.com/en-us/dotnet/api/…的方法 @NigelBess JsonElement 与 PO json 有什么关系?我们正在讨论如何通过名称获取值,而不是关于 JsonElement。 运维问题是关于 JsonElement

以上是关于如何强制 System.Text.Json.JsonElement.GetProperty 使用不区分大小写的方法搜索属性?的主要内容,如果未能解决你的问题,请参考以下文章

强制自己

如何在父组件中强制刷新子组件

css 如何控制span 强制换行

如何让安卓手机强制4G网络模式

如何强制系统关闭底层套接字

当数据库强制加入时,如何强制执行更好的执行计划?