Десерлизация свойств без учета регистра Json.NET
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" vs "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")
Есть ли способ выполнить для десериализации нечувствительности к регистру?
Ответы
Ответ 1
Это ошибка.
десериализация дескрипции нечувствительности к регистру относится к Json.NET, способному сопоставлять свойство JSON с именем "Key" либо с классом .NET, либо с ключом "ключ".
Ошибка: KeyValuePair требует своего JsonConverter, но пропускает нечувствительное к регистру отображение.
https://github.com/JamesNK/Newtonsoft.Json/blob/fe200fbaeb5bad3852812db1e964473e1f881d93/Src/Newtonsoft.Json/Converters/KeyValuePairConverter.cs
Используйте это как базу и добавьте строчный "ключ" и "значение" в оператор case при чтении JSON.
Ответ 2
Одним из эффективных способов я нашел использование GetValue с параметром StringComparer.
Итак, например,
JObject contact;
String strName = contact.GetValue('Name');
Вы пытаетесь получить доступ к свойству "Имя" как к регистру без учета, вы можете использовать
JObject contact;
String strName = contact.GetValue("ObjType", StringComparison.InvariantCultureIgnoreCase);
Ответ 3
Вы можете использовать собственный распознаватель Контракта для имени входящего свойства, которое вы можете изменить для входящего свойства в предпочтительный формат, который будет соответствовать формату свойства вашего класса объектов С#. Я сделал три пользовательских обработчика контрактов, которые изменят имя входящего свойства на Заголовок/Строчные/Верхний регистр:
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(json, jsonSerializerSetting)
var serializerSetting = new JsonSerializerSettings()
{
ContractResolver = new TitleCaseContractResolver()
};
var result = JsonConvert.DeserializeObject<YourType>(msg, serializerSetting);