问题描述
我对 .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
设置为正确
,所以我们保持这种行为.)
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 的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!