2016-11-29 49 views
5

Mam ciąg JSON i klawisze mają wielkie i małe litery:Jak zmienić wszystkie klawisze na małe litery podczas analizowania JSON do JToken

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

Chcę przekonwertować go na JToken obiektu i mają wszystko klucze w JToken są małymi literami. Tak wewnętrznie w JToken powinna być następująca:

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

Wcześniej używałem JToken json = JToken.Parse(jsonString); do konwersji, ale nie mogę dowiedzieć się, jak sprawić, by klawisze małe. Jakieś pomysły?

Powodem, dla którego muszę to zrobić, jest to, że moja walidacja JsonSchema będzie niewrażliwa na wielkość liter.

+0

JProperty ma tylko nazwę Nazwa, więc myślę, że będziesz miał problemy z jej zmianą. – mybirthname

+0

Prawda. Myślałem, że jest jakiś sposób na dostosowanie mechanizmu parsowania. Podobnie do funkcji parsowania js, która ma parametr reviver (https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse), aby edytować parsowanie. Po prostu nie wiem, jak dostosować w json.net. – Rafi

+0

jeśli chcesz utworzyć niestandardowy konwerter Json, sprawdź to. Nie wiem, czy to pomoże w twoim obecnym przypadku: http: //stackoverflow.com/questions/8030538/how-to-implement-custom-jsonconverter-in-json-net-to-deserialize-a-list- of-base – mybirthname

Odpowiedz

4

Jednym z możliwych sposobów rozwiązania tego przy minimalnym kod jest do podklasy JsonTextReader i zastąpić właściwość Value zwrócić małą ciąg gdy prąd TokenType jest 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; 
     } 
    } 
} 

To działa, ponieważ pod spodem JsonTextReader utrzymuje TokenType zaktualizowano jako wewnętrzne zmiany stanu, a moduł serializatora (w rzeczywistości klasa JsonSerializerInternalReader) opiera się na tym, gdy przechodzi do pobrania nazwy właściwości z czytnika za pośrednictwem właściwości Value.

Można tworzyć krótkie metody pomocnika do ułatwiają deserializowania przy użyciu czytnika niestandardowe:

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

Następnie w kodzie, po prostu zastąpić ten:

JToken json = JToken.Parse(jsonString); 

z tym:

JToken json = JsonHelper.DeserializeWithLowerCasePropertyNames(jsonString); 

Fiddle: https://dotnetfiddle.net/A0S3I1

+0

To jest dokładnie to rozwiązanie, którego szukałem. Zmienia się na małe litery podczas analizowania, które są najbardziej skuteczne. – Rafi