title: Serialize/Deserialize complex type to Json with object references and dictionaries that have complex type as key
body: <p>I am trying to serialize/deserialize a complex type. I want object references to be preserved, meaning that if the instance of an object is referenced multiple times in the object graph, during deserialization I want the deserializer to only create that instance once and have it referenced multiple times (vs. create that object instance multiple times).</p>
  
  <p>The second thing I need the system to deal with is a dictionary where the key is a complex type itself.</p>
  
  <p>I was able to achieve both with the DataContractSerializer serializing to XML. However I am failing to find any Json serializer that can do this. I tried Json.NET and ServiceStack, but no luck.</p>
  
  <p>See the sample code below:</p>
  
  <pre><code>using System;
  using System.Collections.Generic;
  using System.IO;
  using System.Linq;
  using System.Runtime.Serialization;
  using System.Text;
  using System.Xml;
  using Newtonsoft.Json;
  
  namespace Serialization
  {
      class Program
      {
  
          static void Main(string[] args)
          {
              var transportModel = CreateSampleModel();
  
  
              //Serialize with DataContractSerializer
              var serializer = new DataContractSerializer(typeof(TransportModel), null, int.MaxValue, false, true, null, null);
              string serializedObjectXml;
              using (var sw = new StringWriter())
              {
                  using (var writer = new XmlTextWriter(sw))
                  {
                      serializer.WriteObject(writer, transportModel);
                      writer.Flush();
                      serializedObjectXml = sw.ToString();
                  }
              }
  
              //Deserialize with DataContractSerializer
              byte[] byteArray = Encoding.ASCII.GetBytes(serializedObjectXml);
              var stream = new MemoryStream(byteArray);
              var deserializedObjectXml = serializer.ReadObject(stream);
  
  
              //Serialize with Json.NET
              var serializedObjectJson=JsonConvert.SerializeObject(transportModel);
  
              //Deserialize with Json.NET - this fails because of the key in the dictionary being a complex type
              var deserializedObjectJson = JsonConvert.DeserializeObject(serializedObjectJson);
          }
  
  
          static TransportModel CreateSampleModel()
          {
              var transportModel = new TransportModel();
  
              // dests
              var fra = new Destination
              {
                  Id = 0,
                  Name = "FRA",
                  Demand = 900
              };
              var det = new Destination
              {
                  Id = 1,
                  Name = "DET",
                  Demand = 1200
              };
  
  
              var dests = new List&lt;Destination&gt; { fra, det};
  
              //origs
              var gary = new Origin
              {
                  Id = 0,
                  Name = "GARY",
                  Supply = 1400,
                  Cost = new Dictionary&lt;Destination, int&gt;{
                      {fra, 39},
                      {det, 14}
                  }
              };
  
  
              var origs = new List&lt;Origin&gt; { gary};
  
              transportModel.Destinations = dests;
              transportModel.Origins = origs;
  
              return transportModel;
          }
      }
  
      [DataContract]
      class Destination
      {
          [DataMember]
          public int Id { get; set; }
          [DataMember]
          public string Name { get; set; }
          [DataMember]
          public int Demand { get; set; }
      }
  
      [DataContract]
      class Origin
      {
          [DataMember]
          public int Id { get; set; }
          [DataMember]
          public string Name { get; set; }
          [DataMember]
          public int Supply { get; set; }
          [DataMember]
          public Dictionary&lt;Destination, int&gt; Cost { get; set; }
      }
  
      [DataContract]
      class TransportModel
      {
          [DataMember]
          public List&lt;Origin&gt; Origins;
          [DataMember]
          public List&lt;Destination&gt; Destinations;
  
          public TransportModel()
          {
              Origins = new List&lt;Origin&gt;();
              Destinations = new List&lt;Destination&gt;();
          }
      }
  }
  </code></pre>