ASP.NET Core 3.0 System.Text.Json骆驼案例序列化

Posted

技术标签:

【中文标题】ASP.NET Core 3.0 System.Text.Json骆驼案例序列化【英文标题】:ASP.NET Core 3.0 System.Text.Json Camel Case Serialization 【发布时间】:2019-10-20 19:45:19 【问题描述】:

在 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 中设置 Camel Case 序列化/反序列化?

谢谢!

【问题讨论】:

【参考方案1】:

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);

【讨论】:

没有办法用 System.Text.Json 为整个项目/应用程序指定序列化选项?这在 System.Text.Json 之前是微不足道的 我不这么认为。您需要通过设置 @AlexanderStaroselsky - 不,见Is There A Way To Globally Set Default Options For System.Text.Json.JsonSerializer?。 This is possible with Json.Net【参考方案2】:

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。

【讨论】:

这对我有用。 FTR,在此之前我的服务中没有 .AddMvc() ,只是添加它以便可以添加 AddJsonOptions 。我所有的服务器-客户端序列化问题都消失了.....【参考方案3】:

如果您想要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;
        );

【讨论】:

【参考方案4】:

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

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

其中(来自docs):

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

因此,它没有指定 camelCase 或 PascalCase,但它会使用不区分大小写的比较。


下面将为通过控制器端点传递的 Json 配置 System.Text.Json:

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

【讨论】:

仅供参考:PropertyNameCaseInsensitive 仅用于传入的 JSON。 ` options.JsonSerializerOptions.PropertyNamingPolicy= null;` 将序列化传出的 JSON PascalCase @PiotrKula 说的是真的...... PropertyNameCaseInsensitive 仅用于传入的 JSON 有效负载,但除了 PropertyNamingPolicy 规定了在序列化期间创建传出 JSON 有效负载的规则之外,它还期望传入的有效负载会马赫反序列化政策;如果没有,您的反序列化类成员将具有默认值 - 这其中 PropertyNameCaseInsensitive 填补了空白,它将允许反序列化成功而不管传入的有效负载大小写。【参考方案5】:

你仍然可以通过安装Microsoft.AspNetCore.Mvc.NewtonsoftJson Nuget 包来设置它的应用程序范围,它允许你使用以前的 Json 序列化器实现:

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

感谢 Poke,在这里找到答案: Where did IMvcBuilder AddJsonOptions go in .Net Core 3.0?

【讨论】:

【参考方案6】:

试试这个!

StartUp.cs里面的ConfigureServices方法写:

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

您需要命名空间,例如 Newtonsoft.Json.Serialization & System.Text.Json

【讨论】:

如果您记录应该去哪里以及这与类似答案有何不同,这会更好,我们怎么知道您不只是复制那些? @MarkSchultheiss 我现在已经做到了。感谢您的反馈。

以上是关于ASP.NET Core 3.0 System.Text.Json骆驼案例序列化的主要内容,如果未能解决你的问题,请参考以下文章

Linq 查询在 ASP.NET-Core 3.0 及更高版本中对数字等字符串进行排序

将 OpenID Connect 与 .NET Core 3.0 ASP.NET Core API 服务一起使用时出错

深入研究 Angular 和 ASP.NET Core 3.0

在 Elastic Beanstalk 上的 Asp.net core 3.0

属性路由在 asp.net core 3.0 中无法正常工作

asp.net core 3.0 MVC JSON 全局配置