ASP.NET Core 3.0 System.Text.Json Сериализация с верблюжьим корпусом

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

Как настроить сериализацию / десериализацию в Camel Case в ASP.NET Core 3.0 с использованием нового пространства имен System.Text.Json?

Спасибо!

Александр Старосельский
источник

Ответы:

25

AddJsonOptions()Конфиг System.Text.Jsonтолько для MVC. Если вы хотите использовать JsonSerializerв своем собственном коде, вы должны передать ему конфигурацию.

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

var json = "{\"firstname\":\"John\",\"lastname\":\"Smith\"}";
var person = JsonSerializer.Parse<Person>(json, options);
Kahbazi
источник
Нет способа указать опции сериализации для всего проекта / приложения с System.Text.Json? Это было тривиально до System.Text.Json
Александр Старосельский
Я так не думаю. Вам нужно пройти настройки
Kahbazi
11

В 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.

sutherlandahoy
источник
Это сработало для меня. FTR, у меня до этого не было .AddMvc () в моих сервисах, я только добавил его, чтобы можно было добавить AddJsonOptions. Все мои проблемы с сериализацией сервер-клиент исчезли ...
Марк Лазз
10

Вы можете использовать PropertyNameCaseInsensitive. Вы должны передать его в качестве параметра десериализатору.

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

который (из документов ):

Получает или задает значение, определяющее, использует ли имя свойства сравнение без учета регистра во время десериализации. Значение по умолчанию неверно

Таким образом, он не определяет camelCase или PascalCase, но будет использовать сравнение без учета регистра. Не уверен, что это соответствует вашим требованиям.


Примечание: я не смог установить это приложение широко в консольном приложении. Как отмечено в ответе Kahbazi в services.AddMvc().AddJsonOptions и services.AddControllers().AddJsonOptionsнастроит JSon только MVC и WebAPI контроллеров (т.е. не будет настроить JSon Настройки приложения широкие в консольном приложении, например). Ниже приведено только конфигурирование System.Text.Json для Json, прошедшего через конечную точку контроллера:

services.AddControllers()
        .AddJsonOptions(options => {
            options.JsonSerializerOptions.PropertyNameCaseInsensitive = true;
         }); 
Haldo
источник
6

Если вы хотите сериализации 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

Вы по-прежнему можете настроить его для всего приложения, установив пакет Nuget Microsoft.AspNetCore.Mvc.NewtonsoftJson, который позволяет использовать предыдущую реализацию сериализатора Json:

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

Кредиты для Poke, ответ найден здесь: Где IMvcBuilder AddJsonOptions находится в .Net Core 3.0?

Пьер-Поль Сен-Пьер
источник