using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Collections.ObjectModel;
using System.Runtime.Serialization;
using System.ComponentModel;
using System.Globalization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Collections.Specialized;
using System.Web.Routing;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Runtime.Serialization.Formatters;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;
using System.Web.SessionState;
public class CartItems : Collection<CartItem>
public CartItems() : base() { }
public CartItems(CartItem parent) : this()
public CartItem Parent { get; private set; }
protected override void RemoveItem(int index)
if (index >= 0 && index < Count)
protected override void InsertItem(int index, CartItem item)
base.InsertItem(index, item);
protected override void SetItem(int index, CartItem item)
if (index >= 0 && index < Count)
base.SetItem(index, item);
protected override void ClearItems()
foreach (var item in this)
this.Children = new CartItems(this);
public int t { get; set; }
public int i { get; set; }
public int n { get; set; }
public bool r { get; set; }
public CartItems Children { get; private set; }
public CartItems Parent { get; set; }
public static class CartItemExtensions
public static IEnumerable<CartItem> DescendantsAndSelf(this CartItem item)
foreach (var child in item.Children)
public static IEnumerable<CartItem> DescendantsAndSelf(this IEnumerable<CartItem> items)
return Enumerable.Empty<CartItem>();
return items.SelectMany(i => i.DescendantsAndSelf());
var json = @"[{""t"":1,""i"":1,""n"":4,""r"":false,""c"":[{""t"":5,""i"":2,""n"":4,""r"":false,""c"":[]}]},{""t"":1,""i"":3,""n"":4,""r"":false,""c"":[{""t"":5,""i"":4,""n"":4,""r"":false,""c"":[{""t"":4,""i"":6,""n"":14,""r"":false,""c"":[]}]},{""t"":1,""i"":5,""n"":15,""r"":false,""c"":[]}]}]";
internal static void Test()
var cookieContent = GetJson();
var root = JsonConvert.DeserializeObject<CartItems>(cookieContent);
Console.WriteLine("Re-serialized JSON: ");
Console.WriteLine(JsonConvert.SerializeObject(root, Formatting.Indented));
foreach (var parent in root.DescendantsAndSelf())
Assert.IsTrue(parent.Children.Parent == parent);
foreach (var child in parent.Children)
Assert.IsTrue(child.Parent == parent.Children);
var newItem = root[0] = new CartItem();
Assert.IsTrue(oldItem.Parent == null);
Assert.IsTrue(root[0].Parent == root);
Assert.IsTrue(newItem.Parent == null);
Console.WriteLine("All parent relationships are set correctly.");
public class AssertionFailedException : System.Exception
public AssertionFailedException() : base() { }
public AssertionFailedException(string s) : base(s) { }
public static class Assert
public static void IsTrue(bool value)
throw new AssertionFailedException("failed");
public static void Main()
Console.WriteLine("Json.NET version: " + typeof(JsonSerializer).Assembly.FullName);