ASP.NET Core 3.0 System.Text.Json Serializacja wielbłądów

19

W projekcie ASP.NET Core 3.0 Web API, jak określasz opcje serializacji System.Text.Json, aby serializować / deserializować właściwości sprawy Pascala do Camel Case i odwrotnie automatycznie?

Biorąc pod uwagę model z właściwościami Pascal Case, takimi jak:

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

I kod do użycia System.Text.Json do deserializacji ciągu JSON do typu Personklasy:

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

Nie można pomyślnie deserializować, chyba że JsonPropertyName jest używana z każdą właściwością, taką jak:

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

Próbowałem następujących startup.csrzeczy, ale nie pomogło to w dalszym ciągu potrzebować 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;
        });

Jak ustawić serializację / deserializację Camel Case w programie ASP.NET Core 3.0 za pomocą nowej przestrzeni nazw System.Text.Json?

Dzięki!

Alexander Staroselsky
źródło

Odpowiedzi:

25

AddJsonOptions()skonfigurowałbym System.Text.Jsontylko dla MVC. Jeśli chcesz użyć JsonSerializerwłasnego kodu, powinieneś przekazać mu konfigurację.

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

var json = "{\"firstname\":\"John\",\"lastname\":\"Smith\"}";
var person = JsonSerializer.Parse<Person>(json, options);
Kahbazi
źródło
Nie ma możliwości określenia opcji serializacji dla całego projektu / aplikacji za pomocą System.Text.Json? Było to trywialne przed System.Text.Json
Alexander Staroselsky
Nie wydaje mi się Musisz przekazać ustawienia
Kahbazi
11

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

Oznacza to, że nie musisz importować pliku newtonsoft.json.

Jedyną inną opcją options.JsonSerializerOptions.PropertyNamingPolicyjest JsonNamingPolicy.CamelCase. Wydaje się, że nie ma żadnych innych JsonNamingPolicyopcji polityki nazewnictwa, takich jak snake_case lub PascalCase.

Sutherlandahoy
źródło
To zadziałało dla mnie. FTR, nie miałem wcześniej .AddMvc () w moich usługach, tylko dodając go, aby można było dodać AddJsonOptions. Wszystkie problemy z serializacją serwer-klient
zniknęły
10

Możesz użyć PropertyNameCaseInsensitive. Musisz przekazać go jako parametr do deserializatora.

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

który (z dokumentów ):

Pobiera lub ustawia wartość określającą, czy nazwa właściwości używa porównania bez rozróżniania wielkości liter podczas deserializacji. Wartość domyślna to false

Nie określa więc camelCase ani PascalCase, ale użyje porównania bez rozróżniania wielkości liter. Nie jestem pewien, czy spełnia twoje wymagania.


Uwaga: nie byłem w stanie ustawić tej aplikacji szeroko w aplikacji konsolowej. Jak wskazano w odpowiedzi Kahbazi za services.AddMvc().AddJsonOptions i services.AddControllers().AddJsonOptionsskonfiguruje json tylko dla kontrolerów MVC i WebAPI (czyli nie będzie konfigurowanie aplikacji JSON ustawieniach szerokiego w app konsoli, na przykład). Poniżej skonfigurujemy tylko System.Text.Json dla Json przekazany przez punkt końcowy kontrolera:

services.AddControllers()
        .AddJsonOptions(options => {
            options.JsonSerializerOptions.PropertyNameCaseInsensitive = true;
         }); 
haldo
źródło
6

Jeśli chcesz serializować CamelCase, użyj tego kodu w Startup.cs : (na przykład firstName)

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

Jeśli chcesz serializacji PascalCase, użyj tego kodu w Startup.cs : (na przykład FirstName)

services.AddControllers()
        .AddJsonOptions(options =>
        {
            options.JsonSerializerOptions.PropertyNamingPolicy= null;
        );
Ramil Alijew
źródło
4

Nadal możesz ustawić tę aplikację na całą instalację, instalując pakiet Microsoft.AspNetCore.Mvc.NewtonsoftJson Nuget, który umożliwia korzystanie z poprzedniej implementacji serializatora Json:

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

Kredyty dla Poke, odpowiedź można znaleźć tutaj: Gdzie wszedł IMvcBuilder AddJsonOptions w .Net Core 3.0?

Pierre-Paul St-Pierre
źródło