【问题标题】:Confused about how to use JSON in C#对如何在 C# 中使用 JSON 感到困惑
【发布时间】:2011-02-26 09:57:43
【问题描述】:

几乎所有关于使用 C# 和 JSON 的问题的答案似乎都是“使用 JSON.NET”,但这不是我要寻找的答案。

我这么说的原因是,从我在文档中读到的所有内容来看,JSON.NET 基本上只是 .NET 框架中内置的 DataContractSerializer 性能更好的版本......

这意味着如果我想反序列化一个 JSON 字符串,我必须为我可能拥有的每个请求定义完整的强类型类。因此,如果我需要获取类别、帖子、作者、标签等,我必须为这些内容中的每一项定义一个新类。

如果我构建了客户端并确切知道字段是什么,这很好,但我使用的是其他人的 API,所以我不知道合同是什么,除非我下载示例响应字符串并手动创建类JSON 字符串。

这是唯一的方法吗?有没有办法让它创建一种可以用 json["propertyname"] 读取的哈希表?

最后,如果我必须自己构建类,当 API 发生变化而他们没有告诉我时会发生什么(因为 twitter 似乎因为这样做而臭名昭著)?我猜我的整个项目都会中断,直到我进入并更新对象属性...

那么使用 JSON 时的一般工作流程到底是什么?一般来说,我的意思是与图书馆无关。我想知道一般情况下它是如何完成的,而不是专门针对目标库...

【问题讨论】:

  • 另外:有没有一种工具可以基于 JSON 字符串自动执行这些数据协定?一些 api 有数十种返回类型,如果尝试将它们全部制作出来会很疯狂......

标签: c# .net json serialization datacontract


【解决方案1】:

我从事 Perl 开发人员已有十多年了,而且我最近才开始使用 C#。我对我有多喜欢它感到惊讶(我根本不喜欢 Java),但最困难的认知转换之一是从“一切都可以被视为字符串并且语言负责转换”到“Pre -定义你的类型。”在这种情况下,字符串思维可能是一个优势,因为这是您需要为您要求的那种 API 做的事情。

您需要编写一个能够理解the syntax 的 JSON 解析器,这相当简单:逗号分隔的列表、键/值对、{} 用于哈希/对象、[] 用于数组以及引用/转义结构。由于 JSON 中的顶级实体始终是一个对象,因此您需要创建一个 Hashtable 开始,然后逐个字符地扫描 JSON 字符串。提取键/值对;如果值以 { 开头,则将其添加为新的 Hashtable,如果以 [ 开头,则将其添加为新的 ArrayList,否则将其添加为字符串。如果您获得 { 或 [ 您将需要递归下降以添加子数据元素。

如果 .NET 有一个很好的递归下降解析器,您可能可以使用它来使工作更简单或更健壮,但 JSON 足够简单,可以使这成为一个很好且相当可完成的练习。

【讨论】:

  • 正如斯蒂芬在他的回复中指出的那样,只要您不依赖于使用的特定键/值,这种方法就可以了。例如,如果您只是显示 JSON 数据结构,则不需要密钥的先验知识。但是,如果您的应用程序要对键名进行硬编码,那么您将被绑定到服务的 API,并且如果 API 发生更改,您可能会中断。也就是说,基于字符串的方法比典型的强类型系统更健壮。像这样的强类型接口通常根本无法处理任何更改,而基于字符串的系统可以使用例如:新键
【解决方案2】:

很难按照您的要求与库无关,因为您使用 json 的方式实际上取决于您使用的库。作为 JSON.NET 中的示例,您可以通过多种方式使用 JSON。您所说的方法是直接序列化为对象。这是类型安全的,但如果您的 API 中的数据发生更改,则会中断。但是,还有一个 LINQ-to-JSON 提供了一个 JObject(其行为与 XElement 非常相似),它提供了一种按照您在问题中请求的方法来执行 JObject["key"] 的方法。如果您真的只是在寻找一种在 C# 中使用 JSON 的灵活方式,请查看 JSON.NET 的 LINQ-to-JSON。

实际上,无论您如何操作,如果 API 发生更改,您的代码都可能会出错。即使您只是严格地基于哈希表的方法,如果返回的数据发生变化,您的代码仍然可能会中断。

编辑

JSON.NET Documentation

Examples

如果您查看示例,第二个示例应该会为您提供一个很好的示例,说明 LINQ-to-JSON 的工作原理。它允许您在不定义任何类的情况下使用它。一切都转换为标准框架类(主要是集合和字符串)。这避免了维护类的需要。

【讨论】:

  • 感谢您的回复! json.net 是否有任何工具来简化这些合同的开发?一些 api 有几十个返回对象,必须全部编写它们会很痛苦,特别是如果我使用它来访问来自不同提供商的多个 api...
  • 使用 JSON.NET Linq 的东西,您不必明确定义返回对象。您可以通过数组使用 JSON,就像在 JavaScript 中一样。用一些链接更新了答案。
  • 啊,示例链接看起来正是我正在寻找的,再次感谢!最后一个问题,如果我确实决定要使用强类型对象,我是否仅限于通过从示例返回的 JSON 字符串映射来手动派生我的类?也就是说,我是否必须发出请求,获取返回的 JSON 字符串,在记事本中打开它并根据我在字符串中看到的字段自己创建类?或者有什么工具可以帮助自动化吗?再次感谢!
  • 我猜你可能需要手动创建它们。我不知道是否存在自动化工具,但编写一个读取 JSON 字符串并输出代码的工具并不难。您可能可以将 LINQ-to-JSON 与 CodeDom 命名空间结合使用来迭代返回的对象并生成一个 C# 类来表示它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-15
  • 2018-01-11
相关资源
最近更新 更多