C# 在ASP.NET Core 3中,是否有一种内置的方式使用snake case作为JSON的命名策略?
我使用以下代码成功地使其工作:C# 在ASP.NET Core 3中,是否有一种内置的方式使用snake case作为JSON的命名策略?,c#,asp.net-core,.net-core,.net-core-3.0,system.text.json,C#,Asp.net Core,.net Core,.net Core 3.0,System.text.json,我使用以下代码成功地使其工作: .AddNewtonsoftJson(options => { options.SerializerSettings.ContractResolver = new DefaultContractResolver { NamingStrategy = new SnakeCaseNamingStrategy() }; }); 然而,这使得MVC使用Newtonsoft而不是System.Text.JSON,后者更快、异步
.AddNewtonsoftJson(options => {
options.SerializerSettings.ContractResolver = new DefaultContractResolver
{
NamingStrategy = new SnakeCaseNamingStrategy()
};
});
然而,这使得MVC使用Newtonsoft
而不是System.Text.JSON
,后者更快、异步且内置
查看
System.Text.JSON
中的命名策略选项,我只能找到CamelCase。snake case是否有本机支持?实现snake-case JSON命名风格的更好方法是什么?目前还没有对snake-case的内置支持,但是
.NET Core 3.0
允许通过继承来设置自定义命名策略
您需要使用snake-case转换实现ConvertName
方法。(Newtonsoft Json.NET有一个内部类,显示如何处理此问题。)
下面的POC实现仅在蛇壳转换中重新使用Json.NET的
SnakeCaseNamingStrategy
(,而整个应用程序使用System.Text.Json
)
最好不要只依赖Newtonsoft Json.Net进行蛇形转换,但在下面这个相当懒惰的示例中,我不想重新思考/重新发明蛇形转换方法。这个答案的要点是如何钩住自定义策略(而不是snake-case转换本身)。(有许多库,展示了如何钩住自定义策略。) 在
Startup.cs
中应用此自定义SnakeCaseNamingPolicy
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers()
.AddJsonOptions(
options => {
options.JsonSerializerOptions.PropertyNamingPolicy =
SnakeCaseNamingPolicy.Instance;
});
}
下面的类的实例
public class WeatherForecast
{
public DateTime Date { get; set; }
public int TemperatureCelcius { get; set; }
public int TemperatureFahrenheit { get; set; }
[JsonPropertyName("Description")]
public string Summary { get; set; }
}
将有一个Json
表示,如下所示:
{ "date" : "2019-10-28T01:00:56.6498885+01:00",
"temperature_celcius" : 48,
"temperature_fahrenheit" : 118,
"Description" : "Cool"
}
请注意,属性摘要
已命名为说明
,匹配其
System.Text.Json.Serialization.JsonPropertyNameAttribute
只需在pfx代码中稍加修改,即可删除对Newtonsoft Json.Net
的依赖
String
extension-mentod将给定字符串转换为SnakeCase
public static class StringUtils
{
public static string ToSnakeCase(this string str)
{
return string.Concat(str.Select((x, i) => i > 0 && char.IsUpper(x) ? "_" + x.ToString() : x.ToString())).ToLower();
}
}
然后在我们的SnakeCaseNamingPolicy中
public class SnakeCaseNamingPolicy : JsonNamingPolicy
{
public static SnakeCaseNamingPolicy Instance { get; } = new SnakeCaseNamingPolicy();
public override string ConvertName(string name)
{
// Conversion to other naming convention goes here. Like SnakeCase, KebabCase etc.
return name.ToSnakeCase();
}
}
最后一步是在Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers()
.AddJsonOptions(
options => {
options.JsonSerializerOptions.PropertyNamingPolicy =
SnakeCaseNamingPolicy.Instance;
});
}
使用该模型:
public class WeatherForecast
{
public DateTime Date { get; set; }
public int TemperatureCelcius { get; set; }
public int TemperatureFahrenheit { get; set; }
public string Summary { get; set; }
}
Json
输出:
{
"date": "2019-10-28T08:26:14.878444+05:00",
"temperature_celcius": 4,
"temperature_fahrenheit": 0,
"summary": "Scorching"
}
我在这里分享@pfx解决方案的完整实现。自定义命名策略(从NewtonSoft复制): 以及示例用法:
var data = new TestSerializer();
data.TimeStamp = DateTime.Now;
data.CPUPower = 10;
var serializeOptions = new JsonSerializerOptions
{
PropertyNamingPolicy = new SnakeCaseNamingPolicy()
};
var json_string = JsonSerializer.Serialize(data, serializeOptions);
Console.WriteLine(json_string);
给出
{“时间戳”:“2020-08-06T00:30:35.3815583-04:00”,“cpu电源”:10}
这有点晚了,但此解决方案也将解决类似ABCItem或MyCPU的情况。
这只是一个概念,您可以对其进行改进,使其更加通用
using System.Collections.Generic;
namespace Extensions
{
public static class StringExtension
{
public static string ToSnakeCase(this string str)
{
// collect the final result
var snakeCase = new List<char>();
// check and add chars (using for loop for performance)
for (int i = 0; i < str.Length; i++)
{
if (i > 0 && char.IsUpper(str[i]) && !char.IsUpper(str[i + 1]))
{
snakeCase.Add('_');
}
snakeCase.Add(str[i]);
}
// build the new string
return new string(snakeCase.ToArray()).ToLower();
}
}
}
var snakeCase = "CPUMeter".ToSnakeCase();
var snakeCase = "PascalCase".ToSnakeCase();
var snakeCase = "camelCase".ToSnakeCase();
使用System.Collections.Generic;
命名空间扩展
{
公共静态类扩展
{
公共静态字符串ToSnakeCase(此字符串str)
{
//收集最终结果
var snakeCase=新列表();
//检查并添加字符(使用for循环提高性能)
对于(int i=0;i0&&char.IsUpper(str[i])&&&char.IsUpper(str[i+1]))
{
蛇壳。加上(“);
}
添加(str[i]);
}
//构建新字符串
返回新字符串(snakeCase.ToArray()).ToLower();
}
}
}
var snakeCase=“CPUMeter”.ToSnakeCase();
var snakeCase=“PascalCase”.ToSnakeCase();
var snakeCase=“camelCase”.ToSnakeCase();
这是一个存储库,其中包含SnakeCase
和KebabCase
NamingPolicy,用于System.Text.Json
JsonSnakeCaseNamingPolicy
var options = new JsonSerializerOptions() { PropertyNamingPolicy = new JsonSnakeCaseNamingPolicy() };
var person = new Person() { FirstName = "Jorge", Birthday = DateTime.UtcNow, MyJobCity = "Madrid" };
var json = JsonSerializer.Serialize(person, options);
var options = new JsonSerializerOptions() { PropertyNamingPolicy = new JsonKebabCaseNamingPolicy() };
var person = new Person() { FirstName = "Jorge", Birthday = DateTime.UtcNow, MyJobCity = "Madrid" };
var json = JsonSerializer.Serialize(person, options);
JsonKebabCaseNamingPolicy
var options = new JsonSerializerOptions() { PropertyNamingPolicy = new JsonSnakeCaseNamingPolicy() };
var person = new Person() { FirstName = "Jorge", Birthday = DateTime.UtcNow, MyJobCity = "Madrid" };
var json = JsonSerializer.Serialize(person, options);
var options = new JsonSerializerOptions() { PropertyNamingPolicy = new JsonKebabCaseNamingPolicy() };
var person = new Person() { FirstName = "Jorge", Birthday = DateTime.UtcNow, MyJobCity = "Madrid" };
var json = JsonSerializer.Serialize(person, options);
我认为asp.NETCore是开箱即用的。不需要额外的配置。我错了吗?它不做蛇的案子,它默认做骆驼的案子,事实上它没有错。C#属性命名约定为。因此,CPU被认为是三个不同的词。您可以使用两种解决方案,一种是使用
[JsonPropertyName(“CPU\u power”)]
,另一种是将属性名称更改为CpuPower
。
var options = new JsonSerializerOptions() { PropertyNamingPolicy = new JsonKebabCaseNamingPolicy() };
var person = new Person() { FirstName = "Jorge", Birthday = DateTime.UtcNow, MyJobCity = "Madrid" };
var json = JsonSerializer.Serialize(person, options);