本文介绍了ASP.Net 核心中所有大写属性名称的默认驼峰式序列化为 JSON 的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对 .Net Core 的默认序列化 CamelCasing 行为有疑问,希望看看其他人是否面临同样的问题以及他们使用的解决方法.

I have an issue with the default serialization CamelCasing behavior of .Net Core and was hoping to see if someone else faced the same issue and what work around they used.

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

Property Names like FOO12 or FOO1 are incorrectly serialized to something like

foO12 或 foO1

foO12 or foO1

事实上,它们可能应该作为 foo12 或 foo1 完成.

When infact they should probably be done as foo12 or foo1.

我使用了添加以下属性的解决方法,但希望有人能对此问题有更好的答案:

I have used a workaround of adding the following Attribute but was hoping somebody might have a better answer to this issue:

[JsonProperty(PropertyName = "foo12")]

[JsonProperty(PropertyName = "foo12")]

推荐答案

Json.NETCamelCasePropertyNamesContractResolver 使用 CamelCaseNamingStrategy 将属性名称转换为驼峰命名.它在内部使用 StringUtils.ToCamelCase,它不会将字符转换为小写,以防后面跟有数字,请参阅 链接.

Json.NET's CamelCasePropertyNamesContractResolver uses a CamelCaseNamingStrategy to convert the property names to camelcase. Internally it uses StringUtils.ToCamelCase which doesn't convert a character to lowercase in case it is followed by a number, see link.

CamelCaseNamingStrategy

public class CamelCaseNamingStrategy : NamingStrategy
{
    // ...

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

StringUtils

注意第二个 if 语句,这里没有检查数字.

Notice the 2nd if statement, where there's no check for a number.

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来实现这个缺失的检查,如下所示.

You can implement a custom NamingStrategy to implement this missing check as shown below.

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 设置为正确,所以我们保持这种行为.)

In ConfigureServices you assign this custom NamingStrategy to the CamelCasePropertyNamesContractResolver.
There's no need to implement a full custom ContractResolver.
(When using the default CamelCaseNamingStrategy, the CamelCasePropertyNamesContractResolver sets the properties ProcessDictionaryKeys and OverrideSpecifiedNames to True, so we keep this behaviour.)

services
    .AddMvc()
    .AddJsonOptions(options =>
        options.SerializerSettings.ContractResolver =
            new CamelCasePropertyNamesContractResolver() {
                NamingStrategy = new CustomCamelCaseNamingStrategy() {
                ProcessDictionaryKeys = true,
                OverrideSpecifiedNames = true
        }});

这篇关于ASP.Net 核心中所有大写属性名称的默认驼峰式序列化为 JSON 的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

05-18 22:29