J'ai une classe DTO qui a une propriété de type jobject
. Cette classe DTO est envoyée / reçoit sur HTTP entre plusieurs services. Jobject est utilisé car le ExtraitdData
n'a pas de propriétés prédéfinies
public class MyDTO { public JObject ExtractedData {get;set;} }
Je convertit ce projet en .NET 5. Qu'est-ce qui est équivalent à Jobject dans .NET 5? J'essaie d'éviter JSONDOCUMENT parce que (à partir du docs ):
JSONDOCUMENT construit une vue en mémoire des données dans un regroupement amortir. Par conséquent, contrairement à Jobject ou Jarray de Newtonsoft.json, le Le type JSONDocument implémente iDisposable et doit être utilisé à l'intérieur d'un Utilisation du bloc.
Je prévois d'utiliser jsonElement
. Est-ce le choix le plus approprié ou existe-t-il un autre type disponible pour contenir JSON en tant qu'objet?
2 Réponses :
dans .net 5 et .net core 3.1 l'équivalent le plus proche de jobject
est en effet jsonElement
afin que vous puissiez modifier votre DTO comme suit:
public class MyDTO { public JsonElement ExtractedData {get;set;} = JsonExtensions.Null; } public static class JsonExtensions { static readonly JsonElement nullElement = CreateNull(); public static JsonElement Null => nullElement; static JsonElement CreateNull() { using var doc = JsonDocument.Parse("null"); return doc.RootElement.Clone(); } }
Pour vous inquiéter de l'élimination de tout document, en interne, le jsonElementConverter
Utilisé par jsonserializer
Renvoie un élément non réduit (en clonage l'élément dans .net 5) .
Cependant, la correspondance n'est pas ex Agissez, alors gardez ce qui suit à l'esprit:
jsonElement
représente toute valeur JSON et correspond donc le plus étroitement à jtoken
pas jobject
. Comme jsonElement
est un struct
il n'y a pas de sous-classe correspondant à un objet JSON. Si vous souhaitez contraindre ExtraitdData
pour être un objet JSON, vous devrez vérifier cela dans le secteur:
public class MyDTO { public JsonElement? ExtractedData {get;set;} }
Puisque jsonElement
est une structure, la valeur par défaut n'est pas null
. Alors c'est quoi? Il s'avère que default (jsonElement)
a valuekind = jsonvaluekind.undfined
:
il n'y a pas de valeur (comme distincte de null).
Si vous essayez de sérialiser un tel par défaut jsonElement
avec jsonSerializer
, une exception sera lancée. C'est à dire. Si vous faites simplement
public class MyDTO { [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] public JsonElement ExtractedData {get;set;} }
Dans .net 5, vous pouvez appliquer [JSONIGNORE (condition = jsonIgnoreCondition.WhenwritingDefault)]
Comme:
var json = JsonSerializer.Serialize(new MyDTO());
Dans .NET Core 3.x JSONIGIGNORECONDITION
n'existe pas, vous pouvez donc définir ExtraitdData
pour être nullable:
public class MyDTO { JsonElement extractedData; public JsonElement ExtractedData { get => extractedData; set { if (value.ValueKind != JsonValueKind.Object // && value.ValueKind != JsonValueKind.Null Uncomment if you want to allow null ) throw new ArgumentException(string.Format("{0} is not a JSON object type", value.ValueKind)); extractedData = value; } } }
Voir aussi les questions connexes:
en novembre 2021, fournit des types pour gérer un objet de document inscripteur en mémoire
modèle (DOM) pour l'accès aléatoire des éléments JSON dans un
Vue des données .net 6
introduit le System.Text.json.nodes Espace de noms qui:
Les quatre nouveaux types sont jsonArray
, jsonObject
, jsonNode
et jsonValue
.
Le type le plus proche de jobject
est jsonObject
qui offre des fonctionnalités similaires.
Voir ci-dessous pour quelques exemples:
public class MyDTO { public JsonObject ExtractedData {get;set;} }
D'autres choses intéressantes qui rendent maintenant en utilisant System.Text.json
beaucoup plus facile dans .net6
sont répertoriées ci-dessous.
Analyse , Créer et manipulation DOM
string s = obj.ToJsonString(); // write pretty json with WriteIndented string s = obj.ToJsonString(new JsonSerializerOptions { WriteIndented = true }));
Si vous avez un jsonElement
(peut-être après désérialiser dans dynamique
, objet
, ou jsonElement
) Vous pouvez appeler créer
, vous avez maintenant un objet DOM navigable et écrivable:
List<Friend> friends = obj["Friends"].AsArray().Deserialize<List<Friend>>();
Vous pouvez ajouter / supprimer les propriétés:
// select Keys List<string> keys = obj.Select(node => node.Key).ToList(); // filter friends var friends = obj["Friends"].AsArray() .Where(n => (int)n.AsObject()["Id"] > 2);
Interroger l'objet en toute sécurité pour une clé particulière en utilisant contientKey
et tryGetPropertyValue (qui renvoie un
jsonNode
):
if (obj.ContainsKey("Hobbies")) // do stuff if (obj.TryGetPropertyValue("Hobbies", out JsonNode? node)) // do stuff with node
Données de projet et de filtre
Il est possible d'utiliser LINQ pour projeter et filtrer le jsonObject
:
obj.Add("FullName", "Bob Smith"); bool successfullyRemoved = obj.Remove("Name");
désérialiser JSON
Il est maintenant facile de désérialiser le JSON ou de désérialiser une partie du JSON. Ceci est utile lorsque nous voulons ne désérialiser JSON partiel de l'objet principal. Pour l'exemple ci-dessus, nous pouvons désérialiser la liste des amis dans une liste générique
facilement:
// create JsonObject obj = JsonObject.Create(jsonElement);
où désériliser
est une méthode d'extension sur jsonNode
.
sérialiser
Il est facile de sérialiser le JsonObject
en utilisant tojSontring ()
:
// parse var jsonObj = JsonNode.Parse(jsonString).AsObject();
Dans votre cas particulier, vous pouvez définir jsonObject code > Dans votre dto:
// create object manually using initializer syntax JsonObject obj = new JsonObject { ["Id"] = 3, ["Name"] = "Bob", ["DOB"] = new DateTime(2001, 02, 03), ["Friends"] = new JsonArray { new JsonObject { ["Id"] = 2, ["Name"] = "Smith" }, new JsonObject { ["Id"] = 4, ["Name"] = "Jones" } } }; // random access to values int id = (int)obj["Id"]; DateTime dob = (DateTime)obj["DOB"]; string firstFriendName = (string)obj["Friends"][0]["Name"];