ASP.NET Core 3 中是否有使用蛇形大小写作为 JSON 命名策略的内置方式?

num*_*jak 10 c# .net-core asp.net-core .net-core-3.0 system.text.json

我设法使用以下代码使其工作:

.AddNewtonsoftJson(options => {
    options.SerializerSettings.ContractResolver = new DefaultContractResolver
    {
        NamingStrategy = new SnakeCaseNamingStrategy()
    };
});
Run Code Online (Sandbox Code Playgroud)

然而,这使得 MVC 使用Newtonsoft而不是System.Text.JSON更快、异步和内置。

查看命名策略选项中System.Text.JSON我只能找到 CamelCase。是否有对蛇盒的本地支持?什么是实现蛇案例 JSON 命名风格的更好方法?

pfx*_*pfx 14

At the moment there's no builtin support for snake case,
but .NET Core 3.0 allows to set up a custom naming policy by inheriting from JsonNamingPolicy.

You need to implement the ConvertName method with the snake case conversion.
(Newtonsoft Json.NET has an internal StringUtils class which shows how to handle this.)


The POC implementation below, re-uses Json.NET's SnakeCaseNamingStrategy only for the snake case conversion (, whereas the whole application uses System.Text.Json).

It is better to avoid having a dependency on Newtonsoft Json.Net for only the snake case conversion, but in this rather LAZY example below I don't want to rethink/reinvent a snake case conversion method.
The main point of this answer is how to hook a custom policy (and not the snake case conversion itself.)
(There are many libraries and code samples that show how to do so.)

public class SnakeCaseNamingPolicy : JsonNamingPolicy
{
    private readonly SnakeCaseNamingStrategy _newtonsoftSnakeCaseNamingStrategy
        = new SnakeCaseNamingStrategy();

    public static SnakeCaseNamingPolicy Instance { get; } = new SnakeCaseNamingPolicy();

    public override string ConvertName(string name)
    { 
        /* A conversion to snake case implementation goes here. */

        return _newtonsoftSnakeCaseNamingStrategy.GetPropertyName(name, false);
    }
}
Run Code Online (Sandbox Code Playgroud)

In Startup.cs you apply this custom SnakeCaseNamingPolicy.

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers()            
        .AddJsonOptions(
            options => { 
                options.JsonSerializerOptions.PropertyNamingPolicy = 
                    SnakeCaseNamingPolicy.Instance;
            });
}
Run Code Online (Sandbox Code Playgroud)

An instance of the class below

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; }
}
Run Code Online (Sandbox Code Playgroud)

will have a Json representation as:

{ "date" : "2019-10-28T01:00:56.6498885+01:00",
  "temperature_celcius" : 48,
  "temperature_fahrenheit" : 118,
  "Description" : "Cool"
}
Run Code Online (Sandbox Code Playgroud)

Note that the property Summary has been given the name Description,
which matches its System.Text.Json.Serialization.JsonPropertyNameAttribute.

  • 仅供参考,有一个 [GitHub 问题](https://github.com/dotnet/runtime/issues/782) 打开,用于直接在“System.Text.Json”中跟踪“JsonSnakeCaseNamingPolicy”的实现。截至 2021 年 7 月 23 日,计划在 .NET7 上实施。 (2认同)

Muh*_*nan 13

只需稍微修改pfx代码即可消除对Newtonsoft Json.Net.

String扩展 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();
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在我们的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();
    }
}
Run Code Online (Sandbox Code Playgroud)

最后一步是注册我们的命名政策 Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers()            
        .AddJsonOptions(
            options => { 
                options.JsonSerializerOptions.PropertyNamingPolicy = 
                    SnakeCaseNamingPolicy.Instance;
            });
}
Run Code Online (Sandbox Code Playgroud)

使用模型:

public class WeatherForecast
{
    public DateTime Date { get; set; }

    public int TemperatureCelcius { get; set; }

    public int TemperatureFahrenheit { get; set; }

    public string Summary { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

Json 输出:

{
  "date": "2019-10-28T08:26:14.878444+05:00",
  "temperature_celcius": 4,
  "temperature_fahrenheit": 0,
  "summary": "Scorching"
}
Run Code Online (Sandbox Code Playgroud)

  • 其实并没有错。C# 属性命名约定是 [PascalCase](/sf/ask/2923811341/)。因此,CPU被认为是三个不同的词。您可以使用两种解决方案:使用“[JsonPropertyName("CPU_power")]”或将属性名称更改为“CpuPower”。 (7认同)