Jak globalnie ustawić domyślne opcje dla System.Text.Json.JsonSerializer?

12

AKTUALIZACJA [23.12.2019]: Po części dzięki wkładowi społeczności głosowej ten problem został dodany do mapy drogowej dla .NET 5.0.

AKTUALIZACJA [10.10.2010]: Jeśli chcesz zobaczyć, jak to zachowanie zostało zaimplementowaneSystem.Text.Json.JsonSerializerprzejdź do otwartego numeru GitHub, na który zwrócił uwagę Chris Yungmann, i zważ.


Zamiast tego:

JsonSerializerOptions options = new JsonSerializerOptions
{
    PropertyNamingPolicy = JsonNamingPolicy.CamelCase
    // etc.
};
JsonSerializer.Deserialize<SomeObject>(someJsonString, options);

Chciałbym zrobić coś takiego:

// This property is a pleasant fiction
JsonSerializer.DefaultSettings = new JsonSerializerOptions
{
    PropertyNamingPolicy = JsonNamingPolicy.CamelCase
    // etc.
};

// This uses my options
JsonSerializer.Deserialize<SomeObject>(someJsonString); 

// And somewhere else in the same codebase...
// This also uses my options
JsonSerializer.Deserialize<SomeOtherObject>(someOtherJsonString); 

Mamy nadzieję, że nie JsonSerializerOptionsbędziemy musieli przekazywać instancji dla naszych najczęstszych przypadków i zastępować wyjątek, a nie regułę.

Jak wskazano w tym pytaniu , jest to przydatna funkcja Json.Net. Spojrzałem w dokumentacji dla System.Text.Jsonjak to repo GitHub for .NET Core. I ten jeden .

Wydaje się, że w .NET Core 3 nie ma analogicznego narzędzia do zarządzania domyślnymi serializacjami JSON. Czy mogę to przeoczyć?

Trevor Reid
źródło
There doesn't seem to be an analog for managing JSON serialization defaults in Core-3- Czy mówisz o żądaniach do i z interfejsu API? lub prośby i odpowiedzi na inne zasoby?
ps2goat,
@ ps2goat Nie jestem pewien, czy rozumiem twoje pytanie. Tutaj chodzi o (de) serializację ciągów JSON. Mogą pochodzić z dowolnej liczby źródeł.
Trevor Reid,
Pytałem, ponieważ istnieją specjalne miejsca podczas uruchamiania dla
formatów
Ach, gotcha. W tym sensie myślę, że nasza sprawa objęłaby „inne zasoby”. @ ps2goat
Trevor Reid,
To naprawdę smutne, dopóki .NET Core 3.1 nie było jeszcze dobrego wbudowanego serializatora json.
Żart Huang

Odpowiedzi:

4

Nie, JsonSerializerOptionsnie ujawnia opcji domyślnych . Jeśli używasz określonego frameworka internetowego, może istnieć sposób określenia (de-) ustawień serializacji za jego pośrednictwem. W przeciwnym razie sugeruję stworzenie własnych metod wygody.

Zobacz także ten otwarty problem .

Chris Yungmann
źródło
3

Możesz utworzyć metodę rozszerzenia. Oto przykład

Używam osobnych metod zamiast budowania specjalnych ustawień, dzięki czemu wszystkie ustawienia będą w jednym miejscu i będą łatwe do ponownego użycia.

public static class DeserializeExtensions
{
    private static JsonSerializerOptions defaultSerializerSettings = new JsonSerializerOptions();

    // set this up how you need to!
    private static JsonSerializerOptions featureXSerializerSettings = new JsonSerializerOptions();


    public static T Deserialize<T>(this string json)
    {       
        return JsonSerializer.Deserialize<T>(json, defaultSerializerSettings);
    }

    public static T DeserializeCustom<T>(this string json, JsonSerializerOptions settings)
    {
        return JsonSerializer.Deserialize<T>(json, settings);
    }

    public static T DeserializeFeatureX<T>(this string json)
    {
        return JsonSerializer.Deserialize<T>(json, featureXSerializerSettings);
    }
}

Następnie wywołujesz go jako metodę na łańcuchu, dosłownym lub zmiennym.

    Car result = @"{""Wheels"": 4, ""Doors"": 2}".DeserializeFeatureX<Car>();
ps2goat
źródło
Ach, twoja jest kolejną odpowiedzią zależną od Json.Net, tak myślę. To pytanie dotyczy System.Text.Json.JsonSerializerNET Core-3.0 bez dodatkowych zależności. Dzięki.
Trevor Reid,
2
To jest piękno abstrakcji. Żadnych zmian kodu poza tą klasą rozszerzeń! Właśnie zaktualizowałem do wbudowanego System.Text.Json.JsonSerializer. Pomysł był dokładnie taki sam. Zaktualizowałem również przykładowy link.
ps2goat,
2

Obejście został zaproponowany przez GitHub użytkownika Andre-SS6 następująco:

((JsonSerializerOptions)typeof(JsonSerializerOptions)
    .GetField("s_defaultOptions", 
        System.Reflection.BindingFlags.Static |
        System.Reflection.BindingFlags.NonPublic).GetValue(null))
    .PropertyNameCaseInsensitive = true;
Trevor Reid
źródło
-1

(Jeśli kiedykolwiek przełączysz się na używanie Json.NET)

Wolę i zalecam jawność i przekazywanie ustawień do wszystkich połączeń, ale możesz ustawić wartości domyślne za pomocą DefaultSettings .

JsonConvert.DefaultSettings = () => MySuperJsonSerializerSettings;

i wtedy

var json = JsonConvert.SerializeObject(o1);
var o2 = JsonConvert.DeserializeObject(x);
tymtam
źródło
Ta odpowiedź i link autorstwa @tymtam dotyczy Json.Net. To pytanie dotyczy podobnego zachowania, w System.Text.Jsonktórym serializacja JSON jest wypalona w .NET Core 3.0. Dzięki za poświęcenie czasu na odpowiedź.
Trevor Reid,