Serialização de caso do Camel System.Text.Json do ASP.NET Core 3.0

19

No projeto da API da Web do ASP.NET Core 3.0, como você especifica as opções de serialização System.Text.Json para serializar / desserializar as propriedades de Pascal Case para Camel Case e vice-versa automaticamente?

Dado um modelo com propriedades Pascal Case, como:

public class Person
{
    public string Firstname { get; set; }
    public string Lastname { get; set; }
}

E código para usar System.Text.Json para desserializar uma string JSON para o tipo de Personclasse:

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

Não desserializa com êxito, a menos que JsonPropertyName seja usado com cada propriedade, como:

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

Tentei o seguinte em startup.cs, mas não ajudou em termos de necessidade 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;
        });

Como você pode definir Camel Case serializar / desserializar no ASP.NET Core 3.0 usando o novo espaço para nome System.Text.Json?

Obrigado!

Alexander Staroselsky
fonte

Respostas:

25

AddJsonOptions()configuraria System.Text.Jsonapenas para MVC. Se você deseja usar JsonSerializerem seu próprio código, deve passar a configuração para ele.

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

var json = "{\"firstname\":\"John\",\"lastname\":\"Smith\"}";
var person = JsonSerializer.Parse<Person>(json, options);
Kahbazi
fonte
Não há como especificar opções de serialização para todo o projeto / aplicativo com System.Text.Json? Isso foi trivial antes de System.Text.Json
Alexander Staroselsky
Acho que não. Você precisa passar as configurações
Kahbazi 20/10/19
11

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

Isso significa que você não precisa importar newtonsoft.json.

A única outra opção para options.JsonSerializerOptions.PropertyNamingPolicyé JsonNamingPolicy.CamelCase. Não parece haver outras JsonNamingPolicyopções de política de nomenclatura, como snake_case ou PascalCase.

sutherlandahoy
fonte
Isso funcionou para mim. FTR, eu não tinha .AddMvc () nos meus serviços antes disso, apenas adicionando-o para que AddJsonOptions pudesse ser adicionado. Todos os meus problemas de serialização servidor-cliente desapareceram ...
Mark Lazz
10

Você pode usar PropertyNameCaseInsensitive . Você precisa passá-lo como um parâmetro para o desserializador.

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

quais (do documentos ):

Obtém ou define um valor que determina se o nome de uma propriedade usa uma comparação sem distinção entre maiúsculas e minúsculas durante a desserialização. O valor padrão é falso

Portanto, ele não especifica camelCase ou PascalCase, mas usará comparação sem distinção entre maiúsculas e minúsculas. Não tenho certeza se isso atende aos seus requisitos.


Nota: Não foi possível definir esse aplicativo em um aplicativo de console. Como observado na resposta de Kahbazi services.AddMvc().AddJsonOptions e services.AddControllers().AddJsonOptionsirá configurar JSON para apenas controladores de MVC e WebAPI (ou seja, não vai configure Json configurações de ampla aplicação em um aplicativo de console, por exemplo). A seguir, apenas será configurado o System.Text.Json for Json transmitido por um ponto de extremidade do controlador:

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

Se você deseja a serialização do CamelCase, use este código em Startup.cs : (por exemplo, firstName)

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

Se você deseja a serialização do PascalCase, use este código em Startup.cs : (por exemplo, FirstName)

services.AddControllers()
        .AddJsonOptions(options =>
        {
            options.JsonSerializerOptions.PropertyNamingPolicy= null;
        );
Ramil Aliyev
fonte
4

Você ainda pode configurá-lo em todo o aplicativo instalando o Pacote Microsoft.AspNetCore.Mvc.NewtonsoftJson Nuget, que permite usar a implementação anterior do serializador Json:

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

Créditos para Poke, resposta encontrada aqui: Para onde foi o IMvcBuilder AddJsonOptions no .Net Core 3.0?

Pierre-Paul-St-Pierre
fonte