在ASP.Net核心中将All Caps属性名称的默认camelCase序列化为JSON的问题

问题描述 投票:1回答:1

我有.Net Core的默认序列化CamelCasing行为的问题,并希望看到其他人是否面临同样的问题以及他们使用了什么工作。

像FOO12或FOO1这样的属性名称被错误地序列化为类似的东西

foO12或foO1

事实上,他们应该以foo 12或foo1完成。

我已经使用了添加以下属性的解决方法,但希望有人可能有更好的答案来解决这个问题:

[JsonProperty(PropertyName =“foo12”)]

c# json .net-core asp.net-core-mvc camelcasing
1个回答
4
投票

Json.NETCamelCasePropertyNamesContractResolver使用CamelCaseNamingStrategy将属性名称转换为camelcase。在内部,它使用StringUtils.ToCamelCase,如果后跟一个数字,它不会将字符转换为小写,请参阅link

CamelCaseNamingStrategy

public class CamelCaseNamingStrategy : NamingStrategy
{
    // ...

    protected override string ResolvePropertyName(string name)
    {
        return StringUtils.ToCamelCase(name);
    }
}

StringUtils的

请注意第二个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;
    }
}

您可以实现自定义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将属性ProcessDictionaryKeysOverrideSpecifiedNames设置为True,所以我们保持这种行为。)

services
    .AddMvc()
    .AddJsonOptions(options => 
        options.SerializerSettings.ContractResolver = 
            new CamelCasePropertyNamesContractResolver() { 
                NamingStrategy = new CustomCamelCaseNamingStrategy() { 
                ProcessDictionaryKeys = true,
                OverrideSpecifiedNames = true 
        }});
© www.soinside.com 2019 - 2024. All rights reserved.