Serializing/Deserializing Dictionary of objects with JSON.NET

I think that is a bug in an older version of Json.NET. If you aren’t already using the latest version, upgrade and try again.

    public class UrlStatus
    {
      public int Status { get; set; }
      public string Url { get; set; }
    }


    [TestMethod]
    public void GenericDictionaryObject()
    {
      Dictionary<string, object> collection = new Dictionary<string, object>()
        {
          {"First", new UrlStatus{ Status = 404, Url = @"http://www.bing.com"}},
          {"Second", new UrlStatus{Status = 400, Url = @"http://www.google.com"}},
          {"List", new List<UrlStatus>
            {
              new UrlStatus {Status = 300, Url = @"http://www.yahoo.com"},
              new UrlStatus {Status = 200, Url = @"http://www.askjeeves.com"}
            }
          }
        };

      string json = JsonConvert.SerializeObject(collection, Formatting.Indented, new JsonSerializerSettings
      {
        TypeNameHandling = TypeNameHandling.All,
        TypeNameAssemblyFormat = FormatterAssemblyStyle.Simple
      });

      Assert.AreEqual(@"{
  ""$type"": ""System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[System.Object, mscorlib]], mscorlib"",
  ""First"": {
    ""$type"": ""Newtonsoft.Json.Tests.Serialization.TypeNameHandlingTests+UrlStatus, Newtonsoft.Json.Tests"",
    ""Status"": 404,
    ""Url"": ""http://www.bing.com""
  },
  ""Second"": {
    ""$type"": ""Newtonsoft.Json.Tests.Serialization.TypeNameHandlingTests+UrlStatus, Newtonsoft.Json.Tests"",
    ""Status"": 400,
    ""Url"": ""http://www.google.com""
  },
  ""List"": {
    ""$type"": ""System.Collections.Generic.List`1[[Newtonsoft.Json.Tests.Serialization.TypeNameHandlingTests+UrlStatus, Newtonsoft.Json.Tests]], mscorlib"",
    ""$values"": [
      {
        ""$type"": ""Newtonsoft.Json.Tests.Serialization.TypeNameHandlingTests+UrlStatus, Newtonsoft.Json.Tests"",
        ""Status"": 300,
        ""Url"": ""http://www.yahoo.com""
      },
      {
        ""$type"": ""Newtonsoft.Json.Tests.Serialization.TypeNameHandlingTests+UrlStatus, Newtonsoft.Json.Tests"",
        ""Status"": 200,
        ""Url"": ""http://www.askjeeves.com""
      }
    ]
  }
}", json);

      object c = JsonConvert.DeserializeObject(json, new JsonSerializerSettings
      {
        TypeNameHandling = TypeNameHandling.All,
        TypeNameAssemblyFormat = FormatterAssemblyStyle.Simple
      });

      Assert.IsInstanceOfType(c, typeof(Dictionary<string, object>));

      Dictionary<string, object> newCollection = (Dictionary<string, object>)c;
      Assert.AreEqual(3, newCollection.Count);
      Assert.AreEqual(@"http://www.bing.com", ((UrlStatus)newCollection["First"]).Url);

      List<UrlStatus> statues = (List<UrlStatus>) newCollection["List"];
      Assert.AreEqual(2, statues.Count);
    }
  }

Edit, I just noticed you mentioned a list. TypeNameHandling should be set to All.

Documentation: TypeNameHandling setting

Leave a Comment