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

19

Dans le projet d'API Web ASP.NET Core 3.0, comment spécifiez-vous les options de sérialisation System.Text.Json pour sérialiser / désérialiser les propriétés de cas Pascal en cas de chameau et vice versa automatiquement?

Étant donné un modèle avec des propriétés Pascal Case telles que:

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

Et codez pour utiliser System.Text.Json pour désérialiser une chaîne JSON en type de Personclasse:

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

Ne désérialise pas correctement sauf si JsonPropertyName est utilisé avec chaque propriété comme:

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

J'ai essayé ce qui suit startup.cs, mais cela n'a pas aidé en termes de besoin 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;
        });

Comment définir la sérialisation / désérialisation de Camel Case dans ASP.NET Core 3.0 à l'aide du nouvel espace de noms System.Text.Json?

Merci!

Alexander Staroselsky
la source

Réponses:

25

AddJsonOptions()config System.Text.Jsonuniquement pour MVC. Si vous souhaitez utiliser JsonSerializerdans votre propre code, vous devez lui passer la configuration.

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

var json = "{\"firstname\":\"John\",\"lastname\":\"Smith\"}";
var person = JsonSerializer.Parse<Person>(json, options);
Kahbazi
la source
Il n'y a aucun moyen de spécifier des options de sérialisation pour l'ensemble du projet / application avec System.Text.Json? C'était trivial avant System.Text.Json
Alexander Staroselsky
Je ne pense pas. Vous devez passer les paramètres
Kahbazi
11

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

Cela signifie que vous n'avez pas besoin d'importer newtonsoft.json.

La seule autre option options.JsonSerializerOptions.PropertyNamingPolicyest JsonNamingPolicy.CamelCase. Il ne semble pas y avoir d'autres JsonNamingPolicyoptions de politique de dénomination, telles que snake_case ou PascalCase.

Sutherlandahoy
la source
Cela a fonctionné pour moi. FTR, je n'avais pas .AddMvc () dans mes services avant cela, l'ajoutant seulement pour que AddJsonOptions puisse être ajouté. Tous mes problèmes de sérialisation serveur-client ont disparu .....
Mark Lazz
10

Vous pouvez utiliser PropertyNameCaseInsensitive. Vous devez le passer en paramètre au désérialiseur.

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

qui (à partir des documents ):

Obtient ou définit une valeur qui détermine si le nom d'une propriété utilise une comparaison non sensible à la casse pendant la désérialisation. La valeur par défaut est false

Ainsi, il ne spécifie pas camelCase ou PascalCase mais il utilisera une comparaison insensible à la casse. Je ne sais pas si cela répond à vos besoins.


Remarque: je n'ai pas pu définir cette application sur une application console. Comme indiqué dans la réponse de Kahbazi services.AddMvc().AddJsonOptions et services.AddControllers().AddJsonOptionsconfigurera Json pour les contrôleurs MVC et WebApi uniquement (c'est-à-dire ne configurera pas l'application des paramètres Json dans une application console, par exemple). Ce qui suit configurera uniquement System.Text.Json pour Json passé par un point de terminaison de contrôleur:

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

Si vous voulez une sérialisation CamelCase, utilisez ce code dans Startup.cs : (par exemple firstName)

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

Si vous voulez une sérialisation PascalCase, utilisez ce code dans Startup.cs : (par exemple FirstName)

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

Vous pouvez toujours le définir à l'échelle de l'application en installant le package Nuget Microsoft.AspNetCore.Mvc.NewtonsoftJson, qui vous permet d'utiliser la précédente implémentation du sérialiseur Json:

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

Crédits à Poke, réponse trouvée ici: Où est passé IMvcBuilder AddJsonOptions dans .Net Core 3.0?

Pierre-Paul St-Pierre
la source