当前位置: 首页 > 面试题库 >

使用JSON.NET序列化/反序列化对象字典

曾阳飙
2023-03-14
问题内容

我正在尝试对a进行序列化/反序列化Dictionary<string, object>,如果对象是简单类型,这似乎很好,但是当对象更复杂时,它不起作用。

我有这个课:

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

在我的字典中,我添加了一个List<UrlStatus>带有“重定向链”键的键和一些带有“状态”,“网址”,“父网址”键的简单字符串。我从JSON.Net返回的字符串如下所示:

{"$type":"System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[System.Object, mscorlib]], mscorlib","Status":"OK","Url":"http://www.ehow.com/m/how_5615409_create-pdfs-using-bean.html","Parent Url":"http://www.ehow.com/mobilearticle35.xml","Redirect Chain":[{"$type":"Demand.TestFramework.Core.Entities.UrlStatus, Demand.TestFramework.Core","Status":301,"Url":"http://www.ehow.com/how_5615409_create-pdfs-using-bean.html"}]}

我用来序列化的代码如下:

JsonConvert.SerializeObject(collection, Formatting.None, new JsonSerializerSettings 
{ 
 TypeNameHandling = TypeNameHandling.Objects, 
 TypeNameAssemblyFormat = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple 
});

反序列化我正在做的事情:

JsonConvert.DeserializeObject<T>(collection, new JsonSerializerSettings
{
 TypeNameHandling = TypeNameHandling.Objects,
 TypeNameAssemblyFormat = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple, 
});

字典恢复正常,所有字符串恢复正常,但是列表未正确反序列化。它只是作为

{[
  {
    "$type": "XYZ.TestFramework.Core.Entities.UrlStatus, XYZ.TestFramework.Core",
    "Status": 301,
    "Url": "/how_5615409_create-pdfs-using-bean.html"
  }
]}

当然,我可以再次对该字符串进行反序列化处理,并且得到正确的对象,但是似乎JSON.Net应该为我完成了此操作。显然我在做错事,但是我不知道那是什么。


问题答案:

我认为这是旧版Json.NET中的错误。如果您尚未使用最新版本,请升级并重试。

    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);
    }
  }

编辑,我刚刚注意到您提到了一个列表。TypeNameHandling应该设置为All。

文档:
TypeNameHandling设置



 类似资料:
  • 问题内容: 我的JSON有点弱,所以我需要一些帮助。 我正在尝试反序列化用户的JSON: 放入我用属性装饰的对象中: 我得到以下异常: Newtonsoft.Json.JsonSerializationException:在JSON中找不到必需的属性’user_id’。 这是因为JSON对象是一个数组吗?如果是这样,如何将其反序列化为一个User对象? 提前致谢! 问题答案: 正如Alexandr

  • 问题内容: 将对象反序列化为()时,嵌套对象反序列化为s。是否可以强制将嵌套对象反序列化为s? 问题答案: 我找到了一种通过提供实现将所有嵌套对象转换为的方法: 文档: Json.NET的CustomCreationConverter

  • 问题内容: 我有以下课程,将其用作字典中的键: 我正在运行的测试在这里: 测试失败,因为Json.Net似乎正在使用字典键上的方法,而不是正确地序列化它们。上面测试得出的json是: 这显然是错误的。我如何使它工作? 问题答案: 这应该可以解决问题: 序列化: 通过调用,您正在序列化一个对象数组而不是字典。 反序列化: 在这里,您可以反序列化数组,然后通过调用检索字典。 我不确定输出是否满足您的期

  • 我需要一个自定义反序列化器来在复杂的POJO中转换字符串。反序列化工作直到使用反序列化器:特别是使用自定义反序列化器时,我的对象的非对象属性不会序列化。 我有一个restful Web服务,它有一个pojo作为参数。 所以我的类PreentivoWs需要一个方法。这里是类定义: 在jsonObject中,我有一个枚举定义为 但此对象需要转换反序列化程序: 并在财产上标注: fromString方法

  • 问题内容: 我有一个问题。我想使用JAXB将一个对象转换为另一个对象。就像在中,我有一个class 和另一个class ,它们都有相同的参数,实际上都是相同的(复制粘贴),但是包不同。我想使用进行它们之间的转换。 怎么做,请帮帮我。 问题答案: 您可以执行以下操作。 注意: 不需要利用JAXBSource将数据具体化为XML。 它在对象模型上不需要任何注释。 com.home.Student co

  • 我在尝试“反序列化”对象时遇到以下错误: 我需要能够使用这个XStream库序列化/反序列化对象,甚至是那些没有参数构造函数的对象。