在ASP.Net Core中将所有Caps属性名称默认序列化为JSON的默认camelCase问题 [英] Issue with Default camelCase serialization of All Caps property names to JSON in ASP.Net core
问题描述
我对.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.NET 的CamelCasePropertyNamesContractResolver
使用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
会将属性ProcessDictionaryKeys
和OverrideSpecifiedNames
设置为True
,因此我们会保持这种行为.)
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 Core中将所有Caps属性名称默认序列化为JSON的默认camelCase问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!