ASP.NET Core 3.0 System.Text.Json Camel Case Serialization

19

En el proyecto de API web ASP.NET Core 3.0, ¿cómo se especifican las opciones de serialización System.Text.Json para serializar / deserializar las propiedades de Pascal Case en Camel Case y viceversa automáticamente?

Dado un modelo con propiedades Pascal Case como:

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

Y código para usar System.Text.Json para deserializar una cadena JSON para el tipo de Personclase:

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

No se deserializa correctamente a menos que se utilice JsonPropertyName con cada propiedad como:

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

Intenté lo siguiente startup.cs, pero no ayudó en términos de necesidad 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;
        });

¿Cómo puede configurar Camel Case serialize / deserialize en ASP.NET Core 3.0 usando el nuevo espacio de nombres System.Text.Json?

¡Gracias!

Alexander Staroselsky
fuente

Respuestas:

25

AddJsonOptions()configuraría System.Text.Jsonsolo para MVC. Si desea utilizar JsonSerializersu propio código, debe pasarle la configuración.

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

var json = "{\"firstname\":\"John\",\"lastname\":\"Smith\"}";
var person = JsonSerializer.Parse<Person>(json, options);
Kahbazi
fuente
No hay forma de especificar las opciones de serialización para todo el proyecto / aplicación con System.Text.Json? Esto fue trivial antes de System.Text.Json
Alexander Staroselsky el
No lo creo. Necesitas pasar la configuración
Kahbazi
11

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

Esto significa que no necesita importar newtonsoft.json.

La única otra opción para options.JsonSerializerOptions.PropertyNamingPolicyes JsonNamingPolicy.CamelCase. No parece haber otras JsonNamingPolicyopciones de política de nombres, como snake_case o PascalCase.

Sutherlandahoy
fuente
Esto funcionó para mí. FTR, no tenía .AddMvc () en mis servicios antes de esto, solo lo agregué para que AddJsonOptions pudiera agregarse. Todos mis problemas de serialización cliente-servidor desaparecieron .....
Mark Lazz
10

Puedes usar PropertyNameCaseInsensitive. Debe pasarlo como parámetro al deserializador.

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

cual (de los documentos ):

Obtiene o establece un valor que determina si el nombre de una propiedad utiliza una comparación que no distingue entre mayúsculas y minúsculas durante la deserialización. El valor predeterminado es falso

Por lo tanto, no especifica camelCase o PascalCase, pero utilizará una comparación que no distingue entre mayúsculas y minúsculas. No estoy seguro si esto cumple con sus requisitos.


Nota: No pude configurar esta aplicación en una aplicación de consola. Como se señaló en la respuesta de Kahbazi services.AddMvc().AddJsonOptions y services.AddControllers().AddJsonOptionsconfigurará Json solo para controladores MVC y WebApi (es decir, no configurará la configuración de Json en toda la aplicación de consola, por ejemplo). Lo siguiente solo configurará System.Text.Json para Json pasado a través de un punto final del controlador:

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

Si desea la serialización de CamelCase, use este código en Startup.cs : (por ejemplo firstName)

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

Si desea la serialización de PascalCase, use este código en Startup.cs : (por ejemplo, FirstName)

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

Todavía puede configurarlo en toda la aplicación instalando Microsoft.AspNetCore.Mvc.NewtonsoftJson Nuget Package, que le permite utilizar la implementación anterior del serializador Json:

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

Créditos para empujar, la respuesta se encuentra aquí: ¿Dónde fue IMvcBuilder AddJsonOptions en .Net Core 3.0?

Pierre-Paul St-Pierre
fuente