2014-10-16 2 views
-1

У меня есть строка json, которую я обрабатываю в JObject, используя JObject.parse(string). Когда я делаю это, все свойства и объекты внутри этой строки json присутствуют, о чем свидетельствует вызов метода ToString(). Однако, как только я называю IEnumerable метод, какJSON.net лишает свойства при итерации по ним

var _mapping = JObject.parse(json); 
var _json = _mapping.ToString(); 
// _json == json at this poing other than some formating 
var map = _mapping["c1-14.10.16"]["mappings"]["applog"]["properties"]; 
foreach(JToken v in map) { 
    string s = v.ToString(); 
    // s != corresponding node string of json 
} 

многие свойства просто исчезают из V и детей V в.

Вот короткий отрывок из JSON, которая не

{"c1-14.10.16":{"mappings":{"applog":{"properties":{"error":{"properties":{"error":{"properties":{"data":{"properties":{"DisablePrepareForRethrow":{"type":"string","index_analyzer":"standard"},"HelpLink.BaseHelpUrl":{"type":"string","index_analyzer":"standard"},"HelpLink.EvtID":{"type":"string","index_analyzer":"standard"},"HelpLink.EvtSrc":{"type":"string","index_analyzer":"standard"},"HelpLink.LinkId":{"type":"string","index_analyzer":"standard"},"HelpLink.ProdName":{"type":"string","index_analyzer":"standard"},"Microsoft.ServiceBus":{"type":"string","index_analyzer":"standard"},"length":{"type":"integer"}}}}}}}}}}}} 

Единственное свойство в "c1-14.10.16".mappings.applog.properties.error.properties.error.properties.data.properties что прослежена length. ни одно из других свойств не распознается вообще.

Что я делаю неправильно, что заставляет его вычеркнуть другие свойства?

ответ

0

Проблема заключается в том, что отправленный json недействителен.

В попытке отредактировать сообщение, чтобы json был более форматированным, сайт, который я использовал, правильно идентифицировал ошибки в вашей строке JSON.

Go here и вставьте JSON там, и вы увидите проблему:

enter image description here

+0

сек orry, если у json опубликовано дополнительное закрытие, я опубликовал только фрагмент, содержащий оскорбительный узел и его происхождение, поскольку оригинал очень большой. Однако это не проблема. Однако я отредактирую сообщение с исправленным json. – danatcofo

+0

@ danatcofo, это не только закрывающая скобка :) Смотрите изображение. –

+0

yah, на самом деле это узел, который я пропустил в своем редактировании. Однако моя точка зрения остается. – danatcofo

1

Свойства есть - но на гораздо более низком уровне, чем ваш код, кажется, ожидать. Вы можете увидеть это следующим образом:

public static void TestJsonParse(string json) 
    { 
     try 
     { 
      var _mapping = JObject.Parse(json); 
      var _json = _mapping.ToString(); 
      // _json == json at this poing other than some formating 

      var map = _mapping["c1-14.10.16"]["mappings"]["applog"]["properties"]; 
      map.WritePropertiesToConsole(); 

      Debug.Assert(map.Count() == 1); // No assert because the properties aren't here. 

      var subMap = _mapping["c1-14.10.16"]["mappings"]["applog"]["properties"]["error"]["properties"]["error"]["properties"]["data"]["properties"]; 
      subMap.WritePropertiesToConsole(); 

      Debug.Assert(subMap.Count() == 8); // no assert - the properties are all here. 
      Debug.Assert(_mapping["c1-14.10.16"]["mappings"]["applog"]["properties"]["error"]["properties"]["error"]["properties"]["data"]["properties"]["Microsoft.ServiceBus"]["index_analyzer"].ToString() == "standard"); // no assert 
     } 
     catch (Exception ex) 
     { 
      Debug.Assert(false, ex.ToString()); // No exception, no assert. 
     } 
    } 

    public static void WritePropertiesToConsole(this JToken subMap) 
    { 
     int iToken = 0; 
     Console.WriteLine(string.Format("Tokens for {0}: {1} found", subMap.Path, subMap.Count())); 
     foreach (JToken v in subMap) 
     { 
      string s = v.ToString(); 
      Console.WriteLine(string.Format("Token {0}: {1}", iToken++, s)); 
     } 
    } 

А вот вывод на консоль:

Tokens for c1-14.10.16.mappings.applog.properties: 1 found 
Token 0: "error": { 
    "properties": { 
    "error": { 
     "properties": { 
     "data": { 
      "properties": { 
      "DisablePrepareForRethrow": { 
       "type": "string", 
       "index_analyzer": "standard" 
      }, 
      "HelpLink.BaseHelpUrl": { 
       "type": "string", 
       "index_analyzer": "standard" 
      }, 
      "HelpLink.EvtID": { 
       "type": "string", 
       "index_analyzer": "standard" 
      }, 
      "HelpLink.EvtSrc": { 
       "type": "string", 
       "index_analyzer": "standard" 
      }, 
      "HelpLink.LinkId": { 
       "type": "string", 
       "index_analyzer": "standard" 
      }, 
      "HelpLink.ProdName": { 
       "type": "string", 
       "index_analyzer": "standard" 
      }, 
      "Microsoft.ServiceBus": { 
       "type": "string", 
       "index_analyzer": "standard" 
      }, 
      "length": { 
       "type": "integer" 
      } 
      } 
     } 
     } 
    } 
    } 
} 

Tokens for c1-14.10.16.mappings.applog.properties.error.properties.error.properties.data.properties: 8 found 
Token 0: "DisablePrepareForRethrow": { 
    "type": "string", 
    "index_analyzer": "standard" 
} 
Token 1: "HelpLink.BaseHelpUrl": { 
    "type": "string", 
    "index_analyzer": "standard" 
} 
Token 2: "HelpLink.EvtID": { 
    "type": "string", 
    "index_analyzer": "standard" 
} 
Token 3: "HelpLink.EvtSrc": { 
    "type": "string", 
    "index_analyzer": "standard" 
} 
Token 4: "HelpLink.LinkId": { 
    "type": "string", 
    "index_analyzer": "standard" 
} 
Token 5: "HelpLink.ProdName": { 
    "type": "string", 
    "index_analyzer": "standard" 
} 
Token 6: "Microsoft.ServiceBus": { 
    "type": "string", 
    "index_analyzer": "standard" 
} 
Token 7: "length": { 
    "type": "integer" 
} 

свойства есть, точно в глубине, указанной в строке JSON, представленной в этом вопросе. Поэтому JSON.net не снимает ничего с предоставленного примера. Вы можете увидеть иерархию явно с помощью http://jsonformatter.curiousconcept.com/:

enter image description here

Если вы измените описание проблемы, чтобы выглядеть следующим образом: «приведены некоторые JSON, как я могу рекурсивно найти ребенка свойство с именем„свойства“с более чем один ребенок собственности», вы можете сделать это так, адаптировано из here:

static IEnumerable<JToken> FindProperties(JToken root) 
    { 
     return root.WalkNodes().Where(n => 
     { 
      var _parent = n.Parent as JProperty; 
      if (_parent != null && _parent.Name == "properties") 
      { 
       if (n.Count() > 1) 
        return true; 
      } 
      return false; 
     }); 
    } 

    public static IEnumerable<JToken> WalkNodes(this JToken node) 
    { 
     if (node.Type == JTokenType.Object) 
     { 
      yield return (JObject)node; 

      foreach (JProperty child in node.Children<JProperty>()) 
      { 
       foreach (var childNode in child.Value.WalkNodes()) 
        yield return childNode; 
      } 
     } 
     else if (node.Type == JTokenType.Array) 
     { 
      foreach (JToken child in node.Children()) 
      { 
       foreach (var childNode in child.WalkNodes()) 
        yield return childNode; 
      } 
     } 
    } 

, а затем, чтобы проверить:

  var _properties = FindProperties(_mapping); 
      var list = _properties.ToArray(); 
      Debug.Assert(list.Length == 1 && list[0] == subMap); // no assert 
+0

К сожалению, это не отвечает на вопрос. Я должен перебирать свойства, я не могу перейти непосредственно к свойствам с помощью индексаторов, как показывает пример кода. Посмотрите на вывод ToString() внутри цикла foreach, и вы увидите, что некоторые свойства просто исчезли. – danatcofo

+0

@danatcofo - ответ обновлен. JSON.net работает правильно с строкой Json, которую вы предоставили.Я добавил предложение о том, как рекурсивно найти узел свойств с более чем одним дочерним свойством. – dbc

+0

Вот огромный головной скребок .... тот же код в консольном приложении находит свойства просто прекрасными, но код внутри контроллера MVC3 теряет свойства .... – danatcofo

Смежные вопросы