using System.Collections;
using System.Collections.Generic;
using System.Runtime.Serialization.Formatters;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;
public partial class KeyIdObject
public string key { get; set; }
public long T_id { get; set; }
public List<KeyIdObject> Children { get; set; }
public partial class KeyIdObject
public static List<KeyIdObject> ToIdObjects(JToken root)
return root.TopDescendantsWhere<JObject>(o => o["T_id"] != null)
.Select(o => new KeyIdObject { key = ((JProperty)o.Parent).Name, T_id = (long)o["T_id"], Children = ToIdObjects(o) })
public partial class KeyIdObject
public bool ShouldSerializeChildren() { return Children != null && Children.Count > 0; }
public static partial class JsonExtensions
public static IEnumerable<TJToken> TopDescendantsWhere<TJToken>(this JToken root, Func<TJToken, bool> predicate) where TJToken : JToken
throw new ArgumentNullException();
return GetTopDescendantsWhere<TJToken>(root, predicate, false);
static IEnumerable<TJToken> GetTopDescendantsWhere<TJToken>(JToken root, Func<TJToken, bool> predicate, bool includeSelf) where TJToken : JToken
var currentOfType = root as TJToken;
if (currentOfType != null && predicate(currentOfType))
yield return currentOfType;
var rootContainer = root as JContainer;
if (rootContainer == null)
var current = root.First;
var currentOfType = current as TJToken;
var isMatch = currentOfType != null && predicate(currentOfType);
yield return currentOfType;
var next = (isMatch ? null : current.FirstChild());
for (var parent = current.Parent; parent != null && parent != root && next == null; parent = parent.Parent)
static JToken FirstChild(this JToken token)
var container = token as JContainer;
return container == null ? null : container.First;
public static void Test()
var root = JToken.Parse(json);
var items = KeyIdObject.ToIdObjects(root);
var newJson = JsonConvert.SerializeObject(items, Formatting.Indented);
Console.WriteLine("Output List<KeyIdObject>: ");
Console.WriteLine(newJson);
Console.WriteLine("\nInput JSON: ");
Assert.IsTrue(JArray.Parse(newJson).SelectTokens("..T_id").Select(i => (long)i).SequenceEqual(root.SelectTokens("..T_id").Select(i => (long)i)));
""T_state"":""Runnerups""
//many more nested n-levels
public static void Main()
Console.WriteLine("Environment version: " + Environment.Version);
Console.WriteLine("Json.NET version: " + typeof(JsonSerializer).Assembly.FullName);
Console.WriteLine("Failed with unhandled exception: ");