【问题标题】:Can I deserialize json to anonymous type in c#?我可以在 c# 中将 json 反序列化为匿名类型吗?
【发布时间】:2011-09-20 13:28:34
【问题描述】:

我从数据库中读取了一个很长的 json。 我只想要那个 json 的一个属性。

我有两个选择: 一种。为该 json 创建一个接口并反序列化为该接口。 (因为我只需要一个属性,所以这是一种矫枉过正的行为吗?) 湾。找到我需要的子字符串(正则表达式?)

哪个更受欢迎?

更新:我使用的是 .net 3.5

【问题讨论】:

    标签: c# regex json .net-3.5


    【解决方案1】:

    您为什么不使用JSON.NET 的“LINQ to JSON”方法(@​​987654322@ 等)进行反序列化,然后通过名称询问您需要的值?

    这是足够动态的,因此您无需为所有内容创建接口,但它比使用正则表达式要脆弱得多。

    JObject json = JObject.Parse(text);
    JToken value = json["foo"]["bar"];
    

    (我相信 JSON.NET 在 .NET 4 中也支持 dynamic,但这里没有特别需要使用它。)

    【讨论】:

      【解决方案2】:

      Regex 必须绝对排除在任何讨论之外。忘记它,就好像它从未存在过一样。

      创建和使用强类型是一件好事,也许我会这样做。

      但如果你愿意,你也可以使用dynamic:

      class Program
      {
          static void Main()
          {
              var json = "{ 'foo': { 'bar': 'bar value', 'baz': [ 1, 2, 3 ] } }";
              var serializer = new JavaScriptSerializer();
              dynamic value = serializer.DeserializeObject(json);
              Console.WriteLine(value["foo"]["baz"][1]);
          }
      }
      

      在控制台上打印2

      【讨论】:

      • 我正在使用 c# 3.5 我认为没有动态类型。对吗?
      • @Elad Benda,不,没有。那么你可以使用Json.NET,它提供了类似的语法。
      【解决方案3】:

      在 .NET 4 上:

      通过使用此处描述的 C# 4.0 的 dynamic 功能,您可以做一些您想要的事情,减去对正则表达式的需求(并且您不应该使用正则表达式!):http://www.drowningintechnicaldebt.com/ShawnWeisfeld/archive/2010/08/22/using-c-4.0-and-dynamic-to-parse-json.aspx

      唯一的缺点是你不能保证对象的确切结构是什么。

      上升之处在于,不是通过yourDynamicObject['blah'] 访问成员,而是更像鸭子类型的yourDynamicObject.blah

      在 .NET 3.5 上:

      您可以使用 Json.NET:http://json.codeplex.com/

      【讨论】:

        【解决方案4】:

        查找子字符串是一个危险的优化。

        是否值得优化流程(与 JSON 反序列化相比)并安全地进行此类查找?我们无法回答,因为它主要取决于上下文。但是我想说NO,因为它显然是在找麻烦:即使它现在可以工作,但将来当你的对象的结构或内容发生变化时,它可能会被破坏。

        【讨论】:

          【解决方案5】:

          旧线程,但这是 .NET 3.5 上的另一种方法:您可以将 DeserializeObject 返回的对象转换为 Dictionary。这与使用 .NET 4.0 动态关键字的解决方案类似:

          JavaScriptSerializer serializer = new JavaScriptSerializer();
          Object obj = serializer.DeserializeObject("{ 'name': 'vinicius fonseca', 'age': 31 }");
          Dictionary<String, Object> ret = (Dictionary<String, Object>)obj;
          Console.WriteLine(ret["name"].GetType().Name); // Output: String
          Console.WriteLine(ret["name"].ToString()); // Output: vinicius fonseca
          Console.WriteLine(ret["age"].GetType().Name); // Output: Int32
          Console.WriteLine(ret["age"].ToString()); // Output: 31
          

          希望对某人有所帮助。

          问候

          【讨论】:

            【解决方案6】:

            你可以这样做:

            var result = JsonConvert.DeserializeAnonymousType(json, new { Foo="", Bar=""});
            

            这将返回一个包含您定义的字段的动态对象。

            【讨论】:

            • 能否请您详细说明您的答案,添加更多关于您提供的解决方案的描述?
            【解决方案7】:

            视情况而定。

            选项 A 是更严格、更规范、更正式的方式。然而,就像你说的那样,这可能有点矫枉过正。那个json有多胖?从长远来看,选项 A 留下了您可能需要使用多个属性的未来潜在可能性。

            选项 B 肯定更加非正式和直接。它今天肯定可以工作,但将来可能需要不同的解决方案。

            因此,也许您希望将整个过程包装在一个方法中,以便对调用客户端隐藏实现。返回仅填充了唯一属性的自定义对象。然后,如果将来需要,您可以更改方法以利用全倾斜反序列化。

            注意:我认为在 C# 3.5 中反序列化为匿名类型是不可能的。

            【讨论】:

              猜你喜欢
              • 2011-01-25
              • 2012-08-05
              • 1970-01-01
              • 1970-01-01
              • 2015-03-17
              • 1970-01-01
              • 2015-09-19
              • 1970-01-01
              • 2017-07-24
              相关资源
              最近更新 更多