Wie werden Standardoptionen für System.Text.Json.JsonSerializer global festgelegt?

12

UPDATE [23.12.2019]: Dieses Problem wurde teilweise aufgrund von Eingaben der Vokal- Community zur Roadmap für .NET 5.0 hinzugefügt .

UPDATE [2019-10-10]: Wenn Sie daran interessiert sind, dieses Verhalten für zu implementierenSystem.Text.Json.JsonSerializerSchauen Sie sich die offene GitHub-Ausgabe an, auf die Chris Yungmann hingewiesen hat, und wiegen Sie sich ab.


An Stelle von:

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

Ich möchte so etwas machen:

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

Die Hoffnung besteht darin, JsonSerializerOptionsfür unsere häufigsten Fälle keine Instanz übergeben zu müssen und die Ausnahme und nicht die Regel außer Kraft zu setzen.

Wie in diesen Fragen und Antworten angegeben , ist dies eine nützliche Funktion von Json.Net. Ich sah in der Dokumentation für System.Text.Jsonsowie das GitHub Repo für .NET - Core. Und dieser hier .

Es scheint kein Analogon für die Verwaltung der Standardeinstellungen für die JSON-Serialisierung in .NET Core 3 zu geben. Oder übersehen Sie es?

Trevor Reid
quelle
There doesn't seem to be an analog for managing JSON serialization defaults in Core-3- Sprechen Sie über Anfragen in und aus Ihrer API? oder Anfragen und Antworten auf andere Ressourcen?
ps2goat
@ ps2goat Ich bin nicht sicher, ob ich deine Frage verstehe. Hier geht es darum, JSON-Strings (zu) serialisieren. Sie könnten aus einer beliebigen Anzahl von Quellen stammen.
Trevor Reid
Ich habe gefragt, weil es beim Start spezielle Stellen für Eingabe- und Ausgabeformatierer gibt (z. B. für die Modellbindung)
ps2goat
Ah, gotcha. In diesem Sinne denke ich, dass unser Fall unter "andere Ressourcen" fallen würde. @ ps2goat
Trevor Reid
Es ist wirklich traurig, bis .net Core 3.1 gab es noch keinen guten eingebauten JSON-Serializer.
Witz Huang

Antworten:

4

Nein, JsonSerializerOptionsmacht die Standardoptionen nicht verfügbar . Wenn Sie ein bestimmtes Webframework verwenden, können Sie möglicherweise (De-) Serialisierungseinstellungen festlegen. Ansonsten schlage ich vor, eigene Convenience-Methoden zu erstellen.

Siehe auch diese offene Ausgabe .

Chris Yungmann
quelle
3

Sie können eine Erweiterungsmethode erstellen. Hier ist ein Beispiel

Ich verwende separate Methoden, anstatt spezielle Einstellungen erstellen zu müssen, damit sich alle Einstellungen an einem einzigen Ort befinden und leicht wiederverwendbar sind.

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

Dann rufen Sie es als Methode für eine Zeichenfolge auf, egal ob Literal oder Variable.

    Car result = @"{""Wheels"": 4, ""Doors"": 2}".DeserializeFeatureX<Car>();
ps2goat
quelle
Ah, deine ist eine andere Json.Net-abhängige Antwort, denke ich. Diese Frage System.Text.Json.JsonSerializerbezieht sich auf den in NET Core-3.0 ohne zusätzliche Abhängigkeiten. Vielen Dank.
Trevor Reid
2
Das ist das Schöne an der Abstraktion. Außerhalb dieser Erweiterungsklasse werden keine Codeänderungen vorgenommen! Ich habe gerade auf die eingebaute aktualisiert System.Text.Json.JsonSerializer. Das Konzept war genau das gleiche. Ich habe auch den Beispiellink aktualisiert.
ps2goat
3

Die Standardoptionen sind in JsonSerializer.NET Core 3.1 nicht verfügbar. Ab Dezember 2019 wurde dies jedoch der Roadmap für 5.0 hinzugefügt .

Die Veröffentlichung von .NET 5.0 wird für November 2020 erwartet . Es gibt jedoch keine Garantie dafür, dass dieses spezielle Problem zu einem bestimmten Zeitpunkt behoben wird. Abgesehen vom Warten schlagen diese Antworten Problemumgehungen vor:

Trevor Reid
quelle
2

Eine Abhilfe wurde von GitHub Benutzer vorgeschlagen underneutes ss6 wie folgt:

((JsonSerializerOptions)typeof(JsonSerializerOptions)
    .GetField("s_defaultOptions", 
        System.Reflection.BindingFlags.Static |
        System.Reflection.BindingFlags.NonPublic).GetValue(null))
    .PropertyNameCaseInsensitive = true;
Trevor Reid
quelle
-1

(Wenn Sie jemals zu Json.NET wechseln)

Ich bevorzuge und empfehle, explizit zu sein und Einstellungen an alle Anrufe zu übergeben, aber Sie können Standardeinstellungen mit DefaultSettings festlegen .

JsonConvert.DefaultSettings = () => MySuperJsonSerializerSettings;

und dann

var json = JsonConvert.SerializeObject(o1);
var o2 = JsonConvert.DeserializeObject(x);
Tymtam
quelle
Diese Antwort und der Link von @tymtam gelten für Json.Net. Diese Frage betrifft ein ähnliches Verhalten, bei dem System.Text.Jsondie JSON-Serialisierung in .NET Core 3.0 integriert ist. Vielen Dank, dass Sie sich die Zeit genommen haben, um zu antworten.
Trevor Reid