ASP.NET Core 3.0 系统的文本 Json 驼峰式序列化

136
在ASP.NET Core 3.0 Web API项目中,如何指定System.Text.Json序列化选项以自动将Pascal Case属性序列化/反序列化为Camel Case,反之亦然?
假设有一个具有Pascal Case属性的模型,例如:
public class Person
{
    public string Firstname { get; set; }
    public string Lastname { get; set; }
}

使用System.Text.Json将JSON字符串反序列化为Person类的类型的代码:

var json = "{\"firstname\":\"John\",\"lastname\":\"Smith\"}";
var person = JsonSerializer.Deserialize<Person>(json);

如果不使用JsonPropertyName,每个属性都需要用它来成功反序列化,例如:

public class Person
{
    [JsonPropertyName("firstname")]
    public string Firstname { get; set; }
    [JsonPropertyName("lastname")]
    public string Lastname { get; set; }
}

我尝试在startup.cs中尝试以下操作,但仍需要JsonPropertyName

services.AddMvc().AddJsonOptions(options =>
{
    options.JsonSerializerOptions.DictionaryKeyPolicy = JsonNamingPolicy.CamelCase;
    options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
});

// also the following given it's a Web API project

services.AddControllers().AddJsonOptions(options => {
    options.JsonSerializerOptions.DictionaryKeyPolicy = JsonNamingPolicy.CamelCase;
    options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
        });

如何使用新的System.Text.Json命名空间在ASP.NET Core 3.0中设置驼峰式大小写序列化/反序列化?

谢谢!


就记录而言,你的Person类具有句子大小写的属性。帕斯卡大小写应该是FirstName和LastName。 - user1007074
1
我在 .net 6 中默认获得了这种行为。正在尝试摆脱它 :D - Anil P Babu
7个回答

148

AddJsonOptions() 仅为 MVC 配置 System.Text.Json。如果你希望在自己的代码中使用 JsonSerializer,则应将配置传递给它。

var options = new JsonSerializerOptions
{
    PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
};

var json = "{\"firstname\":\"John\",\"lastname\":\"Smith\"}";
var person = JsonSerializer.Parse<Person>(json, options);

9
在 System.Text.Json 中无法为整个项目/应用程序指定序列化选项吗?这在 System.Text.Json 之前非常简单。 - Alexander Staroselsky
我不这么认为。你需要传递设置。 - Kahbazi
1
这可以通过Json.Net实现。 - Liam
1
JsonSerializer不包含名为Parse的属性 ??? - Sujoy
如果您需要使用“内置”的内容之外的东西(例如JsonNamingPolicy.CamelCase),请参阅此链接:https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json/customize-properties?pivots=dotnet-core-3-1#use-a-custom-json-property-naming-policy。请注意,JsonNamingPolicy可以应用于json-ELEMENT名称和/或json-VALUES。 - granadaCoder

64
如果您想使用camelCase序列化,请在Startup.cs中使用此代码:(例如firstName)
services.AddControllers()
        .AddJsonOptions(options =>
        {
            options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
        });
如果您想要使用 PascalCase 序列化,请在 Startup.cs 中使用以下代码:(例如 FirstName)
services.AddControllers()
        .AddJsonOptions(options =>
        {
            options.JsonSerializerOptions.PropertyNamingPolicy= null;
        );

PropertyNamingPolicy设置为null解决了这个问题。我最初尝试完全删除这行代码(之前是驼峰命名),但那样并不起作用 - 你需要将其设置为null =) - Ted

56

startup.cs 文件中:

// keeps the casing to that of the model when serializing to json
// (default is converting to camelCase)
services.AddMvc()
    .AddJsonOptions(options => options.JsonSerializerOptions.PropertyNamingPolicy = null); 

这意味着你不需要导入 newtonsoft.json 库。

options.JsonSerializerOptions.PropertyNamingPolicy 的唯一其他选项是 JsonNamingPolicy.CamelCase。似乎没有其他的 JsonNamingPolicy 命名策略选项,例如 snake_case 或 PascalCase。


这对我有用。顺便说一下,在此之前,我的服务中没有 .AddMvc(),只是添加它以便添加 AddJsonOptions。所有我的服务器-客户端序列化问题都消失了..... - Mark Lazarides

24

你可以使用 PropertyNameCaseInsensitive。你需要将它作为参数传递给反序列化器。

var json = "{\"firstname\":\"John\",\"lastname\":\"Smith\"}";
var options = new JsonSerializerOptions() { PropertyNameCaseInsensitive = true };
var person = JsonSerializer.Deserialize<Person>(json, options);

文档中得知:

获取或设置一个值,该值确定在反序列化期间属性名称是否使用不区分大小写的比较。默认值为 false

因此,它不指定camelCase或PascalCase,而是将使用不区分大小写的比较。


以下内容将配置System.Text.Json用于通过控制器端点传递的Json:

services.AddControllers()
        .AddJsonOptions(options => {
            options.JsonSerializerOptions.PropertyNameCaseInsensitive = true;
         }); 

7
“PropertyNameCaseInsensitive” 是针对传入的 JSON 数据的。如果要序列化输出的 JSON 为 PascalCase,需要将选项中的 “JsonSerializerOptions.PropertyNamingPolicy” 设置为 null。 - Piotr Kula
2
@PiotrKula所说的是真的... PropertyNameCaseInsensitive仅用于传入的JSON负载,但除了PropertyNamingPolicy在序列化期间指定传出的JSON负载创建规则之外,它还期望传入的负载将匹配反序列化策略;如果不匹配,则您的反序列化类成员将具有默认值 - 这就是PropertyNameCaseInsensitive填补空白的地方,它将允许反序列化成功,而不管传入负载的大小写。 - PillowMetal

13

您仍然可以通过安装Microsoft.AspNetCore.Mvc.NewtonsoftJson Nuget包来在整个应用程序中进行设置,该包允许您使用先前的Json序列化器实现:

services.AddControllers()
        .AddNewtonsoftJson(options =>
        {
            options.SerializerSettings.ContractResolver = new DefaultContractResolver();
        });

感谢Poke,答案在这里找到: 在 .Net Core 3.0 中,IMvcBuilder AddJsonOptions 去哪了?


7

.NET Core 7 最小API解决方案

为了防止在序列化期间将帕斯卡命名法属性重命名为骆驼命名法,请使用构建器的服务属性的 ConfigureHttpJsonOptions 方法。

builder.Services.ConfigureHttpJsonOptions(options => options.SerializerOptions.PropertyNamingPolicy = null);

要强制将文本转换为驼峰式(默认行为),请使用:

builder.Services.ConfigureHttpJsonOptions(options => options.SerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase);

2

试试这个!

StartUp.cs文件中的ConfigureServices方法内编写:

 services.AddMvc()
                    .AddJsonOptions(options =>
                    options.JsonSerializerOptions.PropertyNamingPolicy
                     = JsonNamingPolicy.CamelCase);

您需要使用命名空间,例如Newtonsoft.Json.SerializationSystem.Text.Json


如果您记录下这个代码应该放在哪里,以及它与其他类似答案的不同之处,那么这将更好。否则我们怎么知道您不是抄袭了别人的答案呢? - Mark Schultheiss
@MarkSchultheiss 我已经完成了。感谢您的反馈。 - Mazz Ebra

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接