2016-11-29 1 views
5

J'ai une chaîne de JSON et les touches ont des caractères majuscules et minuscules:Comment changer toutes les clés en minuscules lors de l'analyse JSON à un JToken

{"employees":[ 
    {"FIrstName":"John", "LASTname":"Doe"}, 
    {"FIRSTNAME":"Anna", "LaSTNaME":"Smith"}, 
    {"firstName":"Peter", "lastName":"Jones"} 
]} 

Je veux le convertir en un objet JToken et ont tous les les touches du JToken soient en minuscules. Ainsi, en interne dans le JToken il devrait être comme suit:

{"employees":[ 
    {"firstname":"John", "lastname":"Doe"}, 
    {"firstname":"Anna", "lastname":"Smith"}, 
    {"firstname":"Peter", "lastname":"Jones"} 
]} 

Auparavant, j'utilisait JToken json = JToken.Parse(jsonString); pour convertir, mais je ne peux pas savoir comment faire les touches minuscules. Des idées?

La raison pour laquelle je dois faire ceci est que ma validation JsonSchema sera insensible à la casse.

+0

JProperty n'a que getter pour Name, donc je pense que vous aurez des problèmes pour le changer. – mybirthname

+0

True. Je pensais qu'il y avait un moyen de personnaliser le mécanisme d'analyse. Similaire à la fonction js parse qui a le paramètre reviver (https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse) pour éditer l'analyse. Je ne suis pas sûr de savoir comment personnaliser dans json.net. – Rafi

+0

si vous voulez créer un convertisseur JSON personnalisé, vérifiez cela. Je ne sais pas si cela va aider dans votre cas actuel: http: //stackoverflow.com/questions/8030538/how-to-implement-custom-jsonconverter-in-json-net-to-deserialize-a-list- de base – mybirthname

Répondre

4

Un moyen de résoudre ce avec un minimum de code est sous-classe le JsonTextReader et passer outre la propriété Value pour retourner une chaîne minuscule chaque fois que le TokenType courant est PropertyName:

public class LowerCasePropertyNameJsonReader : JsonTextReader 
{ 
    public LowerCasePropertyNameJsonReader(TextReader textReader) 
     : base(textReader) 
    { 
    } 

    public override object Value 
    { 
     get 
     { 
      if (TokenType == JsonToken.PropertyName) 
       return ((string)base.Value).ToLower(); 

      return base.Value; 
     } 
    } 
} 

Cela fonctionne parce que le JsonTextReader sous-jacente maintient le TokenType mis à jour en tant que ses changements d'état internes, et le sérialiseur (en fait la classe JsonSerializerInternalReader) s'appuie sur cela quand il va récupérer le nom de propriété du lecteur via la propriété Value.

Vous pouvez créer une méthode courte d'aide pour le rendre facile à désérialiser en utilisant le lecteur personnalisé:

public static class JsonHelper 
{ 
    public static JToken DeserializeWithLowerCasePropertyNames(string json) 
    { 
     using (TextReader textReader = new StringReader(json)) 
     using (JsonReader jsonReader = new LowerCasePropertyNameJsonReader(textReader)) 
     { 
      JsonSerializer ser = new JsonSerializer(); 
      return ser.Deserialize<JToken>(jsonReader); 
     } 
    } 
} 

Ensuite, dans votre code, il suffit de remplacer ceci:

JToken json = JToken.Parse(jsonString); 

avec ceci:

JToken json = JsonHelper.DeserializeWithLowerCasePropertyNames(jsonString); 

Fiddle: https://dotnetfiddle.net/A0S3I1

+0

C'est exactement la solution que je recherchais. Il change en minuscules lors de l'analyse, ce qui est le plus efficace. – Rafi