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 static void Test()
var dropDownList = new[] { "Customer.Id", "Customer.FirstName", "Customer.LastName", "Customer.Address.AddressLine1", "Customer.Address.AddressLine2" };
var selectedDropDownValues = new[] { "Customer.Id", "Customer.FirstName", "Customer.Address.AddressLine1" };
var customerDBList = new [] {
AddressLine2="Linking Road"
AddressLine1="Fedral Highway",
AddressLine2="Louisville"
var rootName = "Customer";
var query = customerDBList
.Select(c => JObject.FromObject(c))
.Select(o => new JObject( new JProperty(rootName, o)))
.Select(o => o.RemoveAllExcept(selectedDropDownValues));
var json = JsonConvert.SerializeObject(query, Formatting.Indented);
Console.WriteLine("Generated JSON: ");
""AddressLine1"": ""1 Street""
""AddressLine1"": ""Fedral Highway""
Assert.IsTrue(JToken.DeepEquals(JToken.Parse(json), JToken.Parse(requiredJson)), "Generated JSON is NOT equivalent to required JSON!");
Console.WriteLine("\nGenerated JSON is equivalent to required JSON.");
public static class JsonExtensions
public static JObject RemoveAllExcept(this JObject obj, IEnumerable<string> paths)
if (obj == null || paths == null)
throw new NullReferenceException();
var keepers = new HashSet<JToken>(paths.SelectMany(path => obj.SelectTokens(path)));
var keepersAndParents = new HashSet<JToken>(keepers.SelectMany(t => t.AncestorsAndSelf()));
foreach (var token in obj.DescendantsAndSelfReversed().Where(t => !keepersAndParents.Contains(t) && !t.AncestorsAndSelf().Any(p => keepers.Contains(p))))
token.RemoveFromLowestPossibleParent();
public static void RemoveFromLowestPossibleParent(this JToken node)
throw new ArgumentNullException();
var contained = node.AncestorsAndSelf().Where(t => t.Parent is JArray || t.Parent is JObject).FirstOrDefault();
public static IEnumerable<JToken> DescendantsAndSelfReversed(this JToken node)
throw new ArgumentNullException();
return RecursiveEnumerableExtensions.Traverse(node, t => ListReversed(t as JContainer));
static IEnumerable<T> ListReversed<T>(this IList<T> list)
for (int i = list.Count - 1; i >= 0; i--)
public static partial class RecursiveEnumerableExtensions
public static IEnumerable<T> Traverse<T>(
Func<T, IEnumerable<T>> children)
var stack = new Stack<IEnumerator<T>>();
stack.Push((children(root) ?? Enumerable.Empty<T>()).GetEnumerator());
var enumerator = stack.Peek();
if (!enumerator.MoveNext())
yield return enumerator.Current;
stack.Push((children(enumerator.Current) ?? Enumerable.Empty<T>()).GetEnumerator());
foreach (var enumerator in stack)
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: ");
public class AssertionFailedException : System.Exception
public AssertionFailedException() : base() { }
public AssertionFailedException(string s) : base(s) { }
public static class Assert
public static void IsTrue(bool value)
public static void IsTrue(bool value, string message)
throw new AssertionFailedException(message ?? "failed");