【问题标题】:Json.NET Case-insensitive Property DeserializationJson.NET 不区分大小写的属性反序列化
【发布时间】:2012-06-29 17:57:21
【问题描述】:

Json.NET 将“不区分大小写的属性反序列化”列为宣传的功能之一。我已经阅读过,将首先尝试匹配指定属性的大小写,如果未找到匹配项,则执行不区分大小写的搜索。然而,这似乎不是默认行为。请参阅以下示例:

var result =
    JsonConvert.DeserializeObject<KeyValuePair<int, string>>(
        "{key: 123, value: \"test value\"}"
    );

// result is equal to: default(KeyValuePair<int, string>)

如果 JSON 字符串被更改以匹配属性的大小写(“Key”和“Value”与“key”和“value”),那么一切都很好:

var result =
    JsonConvert.DeserializeObject<KeyValuePair<int, string>>(
        "{Key: 123, Value: \"test value\"}"
    );

// result is equal to: new KeyValuePair<int, string>(123, "test value")

有没有办法执行不区分大小写的反序列化?

【问题讨论】:

    标签: c# json.net


    【解决方案1】:

    这是一个错误。

    不区分大小写的属性反序列化是指 Json.NET 能够将名为“Key”的 JSON 属性映射到 .NET 类的“Key”或“key”成员。

    错误是 KeyValuePair 需要它自己的 JsonConverter 但错过了不区分大小写的映射。

    https://github.com/JamesNK/Newtonsoft.Json/blob/fe200fbaeb5bad3852812db1e964473e1f881d93/Src/Newtonsoft.Json/Converters/KeyValuePairConverter.cs

    以它为基础,在读取 JSON 时将小写的“key”和“value”添加到 case 语句中。

    【讨论】:

    • 感谢您的解释和修复。我不知道 KeyValuePair 使用了转换器。
    【解决方案2】:

    我发现的一种有效方法是将 GetValue 与 StringComparer 参数一起使用。

    例如,

    JObject contact;
    String strName = contact.GetValue('Name');
    

    您正在尝试以不区分大小写的方式访问“名称”属性,您可以使用

    JObject contact;
    String strName = contact.GetValue("ObjType", StringComparison.InvariantCultureIgnoreCase);
    

    【讨论】:

      【解决方案3】:

      您可以在传入属性名称上使用自定义合同解析器,您可以将传入属性更改为与您的 C# 对象类属性格式匹配的首选格式。我已经制作了三个自定义合同解析器,它将传入的属性名称更改为标题大小写/小写/大写:

      public class TitleCaseContractResolver : DefaultContractResolver
      {
          protected override string ResolvePropertyName(string propertyName)
          {
              //Change the incoming property name into Title case
              var name = string.Concat(propertyName[0].ToString().ToUpper(), propertyName.Substring(1).ToLower());
              return base.ResolvePropertyName(name);
          }
      }
      
      public class LowerCaseContractResolver : DefaultContractResolver
      {
          protected override string ResolvePropertyName(string propertyName)
          {
              //Change the incoming property name into Lower case
              return base.ResolvePropertyName(propertyName.ToLower());
          }
      }
      
      public class UpperCaseContractResolver : DefaultContractResolver
      {
          protected override string ResolvePropertyName(string propertyName)
          {
              //Change the incoming property name into Upper case
              return base.ResolvePropertyName(propertyName.ToUpper());
          }
      }
      

      然后创建一个新的 JsonSerializerSetting 对象,并将您的自定义合约解析器放入属性 ContractResolver。然后将JsonSerializerSetting对象添加到JsonConvert.DeserializeObject(jsonString, jsonSerializerSetting)中的第二个参数中

              var serializerSetting = new JsonSerializerSettings()
              {
                  ContractResolver = new TitleCaseContractResolver()
              };
              var result = JsonConvert.DeserializeObject<YourType>(jsonString, serializerSetting);
      

      【讨论】:

        猜你喜欢
        • 2016-04-06
        • 1970-01-01
        • 2021-05-26
        • 2012-02-22
        • 1970-01-01
        • 1970-01-01
        • 2020-06-08
        • 1970-01-01
        相关资源
        最近更新 更多