Json.NET CamelCasePropertyNamesContractResolver
использует CamelCaseNamingStrategy
для преобразования имен свойств в camelcase. Внутренне он использует StringUtils.ToCamelCase
, который не преобразует символ в нижний регистр, если за ним следует число, см. ссылка .
CamelCaseNamingStrategy
public class CamelCaseNamingStrategy : NamingStrategy
{
// ...
protected override string ResolvePropertyName(string name)
{
return StringUtils.ToCamelCase(name);
}
}
StringUtils
Обратите внимание на 2-й оператор if
, где нет проверки номера.
internal static class StringUtils
{
public static string ToCamelCase(string s)
{
if (!string.IsNullOrEmpty(s) && char.IsUpper(s[0]))
{
char[] array = s.ToCharArray();
for (int i = 0; i < array.Length && (i != 1 || char.IsUpper(array[i])); i++)
{
bool flag = i + 1 < array.Length;
if ((i > 0 & flag) && !char.IsUpper(array[i + 1])) // << Missing check for a number.
{
break;
}
char c = char.ToLower(array[i], CultureInfo.InvariantCulture);
array[i] = c;
}
return new string(array);
}
return s;
}
}
Вы можете реализовать custom NamingStrategy
для реализации этой пропущенной проверки, как показано ниже.
class CustomCamelCaseNamingStrategy : CamelCaseNamingStrategy
{
protected override String ResolvePropertyName(String propertyName)
{
return this.toCamelCase(propertyName);
}
private string toCamelCase(string s)
{
if (!string.IsNullOrEmpty(s) && char.IsUpper(s[0]))
{
char[] array = s.ToCharArray();
for (int i = 0; i < array.Length && (i != 1 || char.IsUpper(array[i])); i++)
{
bool flag = i + 1 < array.Length;
if ((i > 0 & flag) && !char.IsUpper(array[i + 1]) && !char.IsNumber(array[i + 1]))
{
break;
}
char c = char.ToLower(array[i], CultureInfo.InvariantCulture);
array[i] = c;
}
return new string(array);
}
return s;
}
}
В ConfigureServices
этот пользовательский NamingStrategy
назначается на CamelCasePropertyNamesContractResolver
.
Нет необходимости реализовывать полный кастом ContractResolver
.
(При использовании значения по умолчанию CamelCaseNamingStrategy
CamelCasePropertyNamesContractResolver
устанавливает свойства ProcessDictionaryKeys
и OverrideSpecifiedNames
на True
, поэтому мы сохраняем это поведение.)
services
.AddMvc()
.AddJsonOptions(options =>
options.SerializerSettings.ContractResolver =
new CamelCasePropertyNamesContractResolver() {
NamingStrategy = new CustomCamelCaseNamingStrategy() {
ProcessDictionaryKeys = true,
OverrideSpecifiedNames = true
}});