désérialisation JSON partielle et dynamique en C # [duplicate]
J'ai un JSON qui a la forme suivante:
{
"type": "oneOfMyTypes",
"body": {
//object corresponding to the type, contains some key-value pairs"
}
}
La structure de l'objet corps dépend du type. Donc, je veux lire le type, vérifier qu'il s'agit de l'un de mes types prédéfinis, activer le type et analyser le corps dans un objet différent en fonction du type. Les objets corps peuvent être très différents et je ne veux pas créer un objet "super corps" contenant tous les attributs possibles. Je souhaite également utiliser JSON et je ne souhaite utiliser aucun format binaire.
Question: Comment cela peut-il être réalisé en utilisant System.Text.Jsonou Utf8Json?
Jusqu'à présent, j'ai trouvé JsonDocument + JsonElement et Utf8JsonReader. Une fois le type connu, je connais la classe appropriée pour le corps, je voudrais donc utiliser une technique d'analyse simple pour le corps, par exemple en utilisant JsonSerializer.Deserialize.
Réponse ici : La désérialisation polymorphe est-elle possible dans System.Text.Json?
Réponses
En supposant que vous utilisez Newtonsoft.Json:
Lors de la sérialisation, utilisez le TypeNameHandling.Autoparamètre. Cela demande au sérialiseur d'enregistrer également le type d'un objet. Lors de la désérialisation, un objet «corps» de ce type sera reconstruit.
var json = JsonConvert.SerializeObject(testResults,
Formatting.Indented,
new JsonSerializerSettings {
TypeNameHandling = TypeNameHandling.Auto
});
Voir également: https://www.newtonsoft.com/json/help/html/SerializeTypeNameHandling.htm
Si vous pouvez utiliser Json.net (beaucoup plus flexible), vous pouvez utiliser JObject à cette fin:
//First, parse the json as a JObject
var jObj = JObject.Parse(json);
//Now switch the type
switch(jObj["type"].ToString())
{
case "oneOfMyTypes":
var oneType = jObj["body"].ToObject<oneOfMyTypes>();
//process it as you need
break;
case "otherOfMyTypes":
var otherType = jObj["body"].ToObject<otherOfMyTypes>();
//process it...
break;
//...
//unsupported type
default:
throw new InvalidDataException("Unrecognized type");
}