【问题标题】:How to force System.Text.Json.JsonElement.GetProperty to search for properties using case-insensitive method?如何强制 System.Text.Json.JsonElement.GetProperty 使用不区分大小写的方法搜索属性?
【发布时间】: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 方法不区分大小写?

【问题讨论】:

    标签: c# .net system.text.json


    【解决方案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
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-08-03
        • 2012-01-31
        • 1970-01-01
        • 2016-12-02
        • 1970-01-01
        相关资源
        最近更新 更多