Comment définir globalement les options par défaut pour System.Text.Json.JsonSerializer?

12

MISE À JOUR [2019-12-23]: En raison en partie de la contribution de la communauté vocale , ce problème a été ajouté à la feuille de route pour .NET 5.0.

MISE À JOUR [10/10/2019]: Si vous souhaitez voir ce comportement implémenté pourSystem.Text.Json.JsonSerializerdirigez-vous vers le problème ouvert de GitHub signalé par Chris Yungmann et pesez.


Au lieu de cela:

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

Je voudrais faire quelque chose comme ça:

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

L'espoir est de ne pas avoir à passer une instance de JsonSerializerOptionspour nos cas les plus courants, et de passer outre à l'exception, pas à la règle.

Comme indiqué dans ces questions et réponses, il s'agit d'une fonctionnalité utile de Json.Net. J'ai regardé dans la documentation pour System.Text.Jsonainsi que ce dépôt GitHub pour .NET Core. Et celui-là .

Il ne semble pas y avoir d'analogue pour gérer les valeurs par défaut de sérialisation JSON dans .NET Core 3. Ou suis-je en train de l'ignorer?

Trevor Reid
la source
There doesn't seem to be an analog for managing JSON serialization defaults in Core-3- parlez-vous de requêtes entrant et sortant de votre API? ou demandes et réponses à d'autres ressources?
ps2goat
@ ps2goat Je ne suis pas sûr de comprendre votre question. Le problème ici est de (dé) sérialiser les chaînes JSON. Ils peuvent provenir de plusieurs sources.
Trevor Reid
Je demandais parce qu'il y avait des endroits spéciaux au démarrage pour les formateurs d'entrée et de sortie (par exemple, pour la liaison de modèle)
ps2goat
Ah, gotcha. En ce sens, je pense que notre cas relèverait des «autres ressources». @ ps2goat
Trevor Reid
C'est vraiment triste, jusqu'à .net core 3.1, il n'y avait toujours pas de bon sérialiseur json intégré.
Joke Huang

Réponses:

4

Non, JsonSerializerOptionsn'expose pas les options par défaut . Si vous utilisez un cadre Web particulier, il peut y avoir un moyen de spécifier les paramètres de (dé-) sérialisation par ce biais. Sinon, je suggère de créer vos propres méthodes pratiques.

Voir aussi ce problème ouvert .

Chris Yungmann
la source
3

Vous pouvez créer une méthode d'extension. Voici un exemple

J'utilise des méthodes distinctes vs avoir à créer des paramètres spéciaux, de sorte que tous les paramètres soient au même endroit et facilement réutilisables.

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

Ensuite, vous l'appelez comme méthode sur une chaîne, qu'elle soit littérale ou variable.

    Car result = @"{""Wheels"": 4, ""Doors"": 2}".DeserializeFeatureX<Car>();
ps2goat
la source
Ah, la vôtre est une autre réponse dépendante de Json.Net, je pense. Cette question concerne le System.Text.Json.JsonSerializerdans NET Core-3.0 sans dépendances supplémentaires. Merci.
Trevor Reid
2
Voilà la beauté de l'abstraction. Aucun changement de code en dehors de cette classe d'extension! Je viens de mettre à jour la version intégrée System.Text.Json.JsonSerializer. Le concept était exactement le même. J'ai également mis à jour l'exemple de lien.
ps2goat
2

Une solution de contournement a été proposée par l'utilisateur GitHub andre-ss6 comme suit:

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

(Si vous passez à utiliser Json.NET)

Je préfère et recommande d'être explicite et de transmettre les paramètres à tous les appels, mais vous pouvez définir des paramètres par défaut avec DefaultSettings .

JsonConvert.DefaultSettings = () => MySuperJsonSerializerSettings;

et alors

var json = JsonConvert.SerializeObject(o1);
var o2 = JsonConvert.DeserializeObject(x);
tymtam
la source
Cette réponse et ce lien par @tymtam s'appliquent à Json.Net. Cette question concerne le comportement simialr dans System.Text.Jsonlequel la sérialisation JSON est intégrée à .NET Core 3.0. Merci de prendre le temps de répondre.
Trevor Reid