Tec*_*ver 2 c# json camelcasing asp.net-core-mvc .net-core
我对.Net Core的默认序列化CamelCasing行为有问题,希望看到其他人是否也遇到相同的问题,以及他们所使用的解决方法。
属性名称(例如FOO12或FOO1)被错误地序列化为
foO12或foO1
实际上,它们可能应该作为foo12或foo1完成。
我使用了添加以下属性的解决方法,但希望有人可能对此问题有更好的答案:
[JsonProperty(PropertyName =“ foo12”)]
Json.NET的CamelCasePropertyNamesContractResolver使用CamelCaseNamingStrategy的属性名称转换为驼峰。在内部,它使用StringUtils.ToCamelCase不会将字符转换为小写的情况(如果后面跟随数字),请参见link。
CamelCase命名策略
public class CamelCaseNamingStrategy : NamingStrategy
{
// ...
protected override string ResolvePropertyName(string name)
{
return StringUtils.ToCamelCase(name);
}
}
Run Code Online (Sandbox Code Playgroud)
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;
}
}
Run Code Online (Sandbox Code Playgroud)
您可以实现一个自定义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;
}
}
Run Code Online (Sandbox Code Playgroud)
在ConfigureServices分配这个定制NamingStrategy的CamelCasePropertyNamesContractResolver。
无需实现完全自定义ContractResolver。
(使用default时CamelCaseNamingStrategy,CamelCasePropertyNamesContractResolver将属性ProcessDictionaryKeys和设置OverrideSpecifiedNames为True,因此我们保持这种行为。)
services
.AddMvc()
.AddJsonOptions(options =>
options.SerializerSettings.ContractResolver =
new CamelCasePropertyNamesContractResolver() {
NamingStrategy = new CustomCamelCaseNamingStrategy() {
ProcessDictionaryKeys = true,
OverrideSpecifiedNames = true
}});
Run Code Online (Sandbox Code Playgroud)