using Newtonsoft.Json.Linq;
using System.Collections.Generic;
public static void Main(string[] args)
private static void SortGraphTest()
var sortGraph = new JObject();
"patient.caregiver.lastName",
"-patient.caregiver.city"
sortPaths.Aggregate(sortGraph, (graph, path) =>
var pathParts = path.Split('.');
foreach (var pathPart in pathParts)
var nextNode = currentNode[pathPart] as JObject;
nextNode = new JObject();
currentNode[pathPart] = nextNode;
Console.WriteLine(sortGraph.ToString(Formatting.Indented));
private static void SingleDepthSort()
var sortGraph = sortPaths.Aggregate(new JObject(), (graph, path) =>
var pathParts = path.Split('.');
foreach (var pathPart in pathParts)
var nextNode = node[pathPart] as JObject;
nextNode = new JObject();
node[pathPart] = nextNode;
var root = new ResourceRoot
Data = JToken.FromObject(new List<Resource>
Attributes = JObject.FromObject(new {firstName = "Mitchell", lastName = "Engen"})
Attributes = JObject.FromObject(new {firstName = "Marvin", lastName = "Engen"})
Attributes = JObject.FromObject(new {firstName = "Justin", lastName = "Case"})
Attributes = JObject.FromObject(new {firstName = "Brian", lastName = "Engen"})
Attributes = JObject.FromObject(new {firstName = "Rachel", lastName = "Engen"})
Attributes = JObject.FromObject(new {firstName = "Charity", lastName = "Case"})
Attributes = JObject.FromObject(new {firstName = "Peggy", lastName = "Engen"})
var data = root.Data as JArray;
Console.WriteLine(JsonConvert.SerializeObject(root, Formatting.Indented));
private static void Sort(JContainer jResources, JObject sortGraph, bool? sortDescending = null)
IOrderedEnumerable<JToken> orderedEnumerable = null;
foreach (var sortNode in sortGraph.Properties())
var desc = sortDescending ?? sortNode.Name.StartsWith("-");
var sortAttr = sortNode.Name.Replace("-", "");
var orderBy = sortNode == sortGraph.Properties().First();
if (sortNode.Value.Any())
foreach (var jResource in jResources)
var resource = jResource.ToObject<Resource>();
Relationship relationship;
if (resource.Relationships.TryGetValue(sortAttr, out relationship))
if (orderBy || orderedEnumerable == null)
? jResources.OrderByDescending(x => GetAttributeValue(x, sortAttr))
: jResources.OrderBy(x => GetAttributeValue(x, sortAttr));
? orderedEnumerable.ThenByDescending(x => GetAttributeValue(x, sortAttr))
: orderedEnumerable.ThenBy(x => GetAttributeValue(x, sortAttr));
jResources.ReplaceAll(orderedEnumerable.ToArray());
private static string GetAttributeValue(JToken resource, string attrName)
var jValue = resource.SelectToken("$.attributes."+attrName);
return jValue.Type == JTokenType.Null
: jValue.Value<string>();
private static IEnumerable<Resource> EnumerableData(JToken dataToken)
if (dataToken.Type == JTokenType.Array)
return dataToken.ToObject<IEnumerable<Resource>>();
return new List<Resource> { dataToken.ToObject<Resource>() };
public class ResourceRoot : JModel
[JsonProperty("data", NullValueHandling = NullValueHandling.Ignore)]
public JToken Data { get; set; }
public class Resource : ResourceIdentifier
[JsonProperty("attributes", NullValueHandling = NullValueHandling.Ignore)]
public JObject Attributes { get; set; }
[JsonProperty("relationships", NullValueHandling = NullValueHandling.Ignore)]
public IDictionary<string, Relationship> Relationships { get; set; }
[JsonProperty("links", NullValueHandling = NullValueHandling.Ignore)]
public IDictionary<string, JToken> Links { get; set; }
public static Resource FromJson(string json)
return JsonConvert.DeserializeObject<Resource>(json);
public class Relationship : JModel
[JsonProperty("links", NullValueHandling = NullValueHandling.Ignore)]
public IDictionary<string, JToken> Links { get; set; }
public JToken Data { get; set; }
[JsonProperty("meta", NullValueHandling = NullValueHandling.Ignore)]
public IDictionary<string, JToken> Meta { get; set; }
public static Relationship FromJson(string json)
return JsonConvert.DeserializeObject<Relationship>(json);
public class ResourceIdentifier : JModel
public Guid Id { get; set; }
[JsonProperty("type", NullValueHandling = NullValueHandling.Ignore)]
public string Type { get; set; }
public abstract class JModel
public virtual string ToJson()
return JsonConvert.SerializeObject(this, Formatting.None, new JsonSerializerSettings
NullValueHandling = NullValueHandling.Ignore