2017-10-20 11 views
2

Je reçois un gros objet json imbriqué à partir d'une API externe. Je veux m'assurer que tous les champs sont remplis dans cet objet json. Y a-t-il des bibliothèques disponibles pour faire cela? Newtonsoft.Json a JToken classe qui vérifie si le schéma de Json est valide ou non mais je ne trouve aucune méthode pour vérifier si tous les champs à l'intérieur de l'objet json sont remplis.Comment vérifier si l'objet JSON a toutes les valeurs remplies

Scénario: Je construis une API qui rassemble des informations sur une personne ou une entité. il existe de nombreuses sources d'information. Je dois continuer à chercher les données jusqu'à ce que l'objet requis soit plein. Donc le premier appel va à api1, obtient des données, vérifie si l'objet est plein. Si l'objet n'est pas plein alors va à api2 et ainsi de suite. Ainsi, l'appel revient après que l'objet soit plein. Un point clé est que le schéma d'objet requis n'est pas statique.

Je pourrais le désérialiser à un POCO et faire une boucle à travers chaque objet imbriqué mais je cherche une meilleure solution.

Toute suggestion est fortement appréciée.

+1

Vous pouvez utiliser 'RequireObjectPropertiesContractResolver' de [Json.NET requiert toutes les propriétés lors de la désérialisation] (https://stackoverflow.com/a/29660550/3744182). Il n'est pas clair à partir de votre question si vous voulez ['Required.Always' ou' Required.AllowNull'] (https://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_Required.htm). – dbc

+0

J'ai besoin de «Required.Always». Donc, il vérifie tout en désérialisant? Est-ce que cela s'applique également aux enfants? – Venky

+0

Y at-il de toute façon parvenir au même résultat sans désérialiser le json? – Venky

Répondre

2

Si vous avez une chaîne JSON et que vous voulez simplement vérifier si une valeur de propriété ou un élément de tableau sont null, vous pouvez analyser à un JToken, descendre récursivement la hiérarchie JToken avec JContainer.DescendantsAndSelf(), et vérifier chaque JValue pour être null en utilisant la méthode d'extension suivant:

public static partial class JsonExtensions 
{ 
    public static bool AnyNull(this JToken rootNode) 
    { 
     if (rootNode == null) 
      return true; 
     // You might consider using some of the other checks from JsonExtensions.IsNullOrEmpty() 
     // from https://stackoverflow.com/questions/24066400/checking-for-empty-null-jtoken-in-a-jobject 
     return rootNode.DescendantsAndSelf() 
      .OfType<JValue>() 
      .Any(n => n.Type == JTokenType.Null); 
    } 

    public static IEnumerable<JToken> DescendantsAndSelf(this JToken rootNode) 
    { 
     if (rootNode == null) 
      return Enumerable.Empty<JToken>(); 
     var container = rootNode as JContainer; 
     if (container != null) 
      return container.DescendantsAndSelf(); 
     else 
      return new[] { rootNode }; 
    } 
} 

Et puis faire:

var root = JToken.Parse(jsonString); 
var anyNull = root.AnyNull(); 

Si vous voulez juste pour vérifier la valeur des propriétés null (à savoir les valeurs NULL dans un tableau sont OK), vous pouvez utiliser la méthode d'extension suivante:

public static partial class JsonExtensions 
{ 
    public static bool AnyNullPropertyValues(this JToken rootNode) 
    { 
     if (rootNode == null) 
      return true; 
     return rootNode.DescendantsAndSelf() 
      .OfType<JProperty>() 
      .Any(p => p.Value == null || p.Value.Type == JTokenType.Null); 
    } 
} 

(Il est pas tout à fait claire de votre question que vous voulez.)

Echantillon .Net fiddle.

+0

@BrianRogers - bonne idée, fait. – dbc

2

Si je vous ai bien compris, vous avez un objet JSON complexe, avec un ensemble de propriétés obligatoires et non requises.

Je vois ici trois solutions:

  1. Vous avez déjà mentionné la validation du schéma JSON. Voici l'une des implémentations: Json.NET Schema.
  2. Créez un objet POCO et marquez toutes les propriétés avec les attributs Required/Not-Required correspondants. Dans ce cas, vous obtiendrez des exceptions si une chaîne json ne contient aucune donnée obligatoire. Par exemple, comment cela se fait en termes de Json.NET's JsonPropertyAttribute:

    [JsonObject] 
    public class PocoObject 
    { 
        [JsonProperty("$schema", Required = Required.Default, NullValueHandling = NullValueHandling.Ignore)] 
        public string Schema { get; set; } 
    
        [JsonProperty("name", Required = Required.Always)] 
        public string Name { get; set; } 
    
        [JsonProperty("properties", Required = Required.Always)] 
        public MorePropertiesObject Properties { get; set; } 
    } 
    

    En prime, vous pouvez ajouter vos attributs personnalisés, des méthodes, des convertisseurs, etc.

  3. Deserialize JSON cru dans une structure de dictionnaire comme et valider avec votre propre validateur manuscrit. Quelque chose comme:

    try 
    { 
        var jo = JObject.Parse(jsonString); 
        Contract.Assert(!string.IsNullOrEmpty(jo["root"]["prop1"].ToString())); 
        Contract.Assert(!string.IsNullOrEmpty(jo["root"]["prop2"].ToString())); 
    } 
    catch (JsonReaderException) { } 
    catch (JsonSerializationException) { } 
    

exemples de code fournis sont pour que vous avez mentionnés Newtonsoft.Json

+0

Merci Ihor. Mais la réponse à l'objet json n'est pas statique. il varie et toutes les propriétés à l'intérieur de cet objet sont requises. Donc, si je passe un objet json aléatoire, il devrait me renvoyer si toutes les propriétés sont remplies ou non. – Venky

+0

@Venky, dbc a proposé une version améliorée de ma 3ème variante, et cela devrait convenir à votre problème. Gardez à l'esprit que si vous devez aussi valider des tableaux vides, vous devez ajouter une autre vérification dans la méthode 'AnyNull()' (tableaux dans Json.net représentés par l'objet 'JArray'.) –