ASP.NET Core 3.1 web API JSON 响应比第一个字符更驼化
ASP.NET Core 3.1 web API JSON response camelizes more than first character
在我们的网络 API 中,我们有使用缩写名称的遗留实体。我们还通过 T4 模板使用代码生成,我们希望让事情变得简单和可预测:
- 模板创建 C# 类 并将属性的第一个字符大写
- 模板创建 Angular 代码并将属性的第一个字符小写
然而,来自网络 JSON 的响应 API 在决定将哪些字母转换为小写而不是仅将预期的第一个字符转换为小写方面发挥了一些作用。
例如,当在 Visual Studio 中启动一个新的默认网站 API 并向 WeatherForecast.cs
添加两个属性时:
public string TSTValue { get; set; }
public string TSTVL1 { get; set; }
结果是:
[
{
...
"tstValue":null,
"tstvL1":null
},
{
...
"tstValue":null,
"tstvL1":null
}
]
expected/desired 输出将是驼峰式 属性 名称的结果:
[
{
...
"tSTValue":null,
"tSTVL1":null
},
{
...
"tSTValue":null,
"tSTVL1":null
}
]
魔法行为如何被覆盖?
首先,您描述的行为是有意为之的。您可以在 Github https://github.com/dotnet/runtime/blob/master/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonCamelCaseNamingPolicy.cs 上查看源代码,幸运的是,可以相对轻松地自定义名称序列化。
由于您指定不想使用属性,因此您可以创建自己的 JsonNamingPolicy
,它可用于以您认为合适的任何方式序列化字段名称。
下面我创建了一个基本的 class,它确保第一个字符是小写的,并保留字段字符串的其余部分。 ConvertName(string name)
将为序列化 class 中的每个字段调用。在你的例子中是 TSTValue
和 TSTVL1
public class JsonFirstCharToLowerNamingPolicy : JsonNamingPolicy
{
public override string ConvertName(string name)
{
// if the string is empty or the first character is already lowercase just return as is
if (string.IsNullOrEmpty(name) || char.IsLower(name[0]))
return name;
char[] chars = name.ToCharArray(); // get a list of chars
chars[0] = char.ToLowerInvariant(chars[0]); // make the first character lower case
// leave the rest of the characters alone or do more processing on it?
return new string(chars); // return the altered string
}
}
要使用 class,您只需设置 JsonSerializerOptions
的 JsonSerializerOptions
,如下所示。
var serializeOptions = new JsonSerializerOptions
{
PropertyNamingPolicy = new JsonFirstCharToLowerNamingPolicy(),
WriteIndented = true
};
var jsonString = JsonSerializer.Serialize(weatherForecast, serializeOptions);
在我们的网络 API 中,我们有使用缩写名称的遗留实体。我们还通过 T4 模板使用代码生成,我们希望让事情变得简单和可预测:
- 模板创建 C# 类 并将属性的第一个字符大写
- 模板创建 Angular 代码并将属性的第一个字符小写
然而,来自网络 JSON 的响应 API 在决定将哪些字母转换为小写而不是仅将预期的第一个字符转换为小写方面发挥了一些作用。
例如,当在 Visual Studio 中启动一个新的默认网站 API 并向 WeatherForecast.cs
添加两个属性时:
public string TSTValue { get; set; }
public string TSTVL1 { get; set; }
结果是:
[
{
...
"tstValue":null,
"tstvL1":null
},
{
...
"tstValue":null,
"tstvL1":null
}
]
expected/desired 输出将是驼峰式 属性 名称的结果:
[
{
...
"tSTValue":null,
"tSTVL1":null
},
{
...
"tSTValue":null,
"tSTVL1":null
}
]
魔法行为如何被覆盖?
首先,您描述的行为是有意为之的。您可以在 Github https://github.com/dotnet/runtime/blob/master/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonCamelCaseNamingPolicy.cs 上查看源代码,幸运的是,可以相对轻松地自定义名称序列化。
由于您指定不想使用属性,因此您可以创建自己的 JsonNamingPolicy
,它可用于以您认为合适的任何方式序列化字段名称。
下面我创建了一个基本的 class,它确保第一个字符是小写的,并保留字段字符串的其余部分。 ConvertName(string name)
将为序列化 class 中的每个字段调用。在你的例子中是 TSTValue
和 TSTVL1
public class JsonFirstCharToLowerNamingPolicy : JsonNamingPolicy
{
public override string ConvertName(string name)
{
// if the string is empty or the first character is already lowercase just return as is
if (string.IsNullOrEmpty(name) || char.IsLower(name[0]))
return name;
char[] chars = name.ToCharArray(); // get a list of chars
chars[0] = char.ToLowerInvariant(chars[0]); // make the first character lower case
// leave the rest of the characters alone or do more processing on it?
return new string(chars); // return the altered string
}
}
要使用 class,您只需设置 JsonSerializerOptions
的 JsonSerializerOptions
,如下所示。
var serializeOptions = new JsonSerializerOptions
{
PropertyNamingPolicy = new JsonFirstCharToLowerNamingPolicy(),
WriteIndented = true
};
var jsonString = JsonSerializer.Serialize(weatherForecast, serializeOptions);