Runtime: .NET Core 3.0 中 JSON 的未来

创建于 2018-10-29  ·  193评论  ·  资料来源: dotnet/runtime

JSON 已成为几乎所有现代 .NET 应用程序的重要组成部分,在许多情况下甚至超过了 XML 的使用。 但是,.NET 还没有(很棒的)内置方式来处理 JSON。 相反,我们依赖 [Json.NET],它继续为 .NET 生态系统提供良好的服务。

展望未来,我们计划对 JSON 支持进行一些更改:

  • 我们需要高性能的 JSON API 。 我们需要一组新的 JSON API,它们通过使用Span<T>对性能进行了高度调整,并允许直接处理 UTF-8,而无需转码为 UTF-16 string实例。 这两个方面对于我们的 Web 服务器 Kestrel 都至关重要,其中吞吐量是一个关键要求。

  • 删除从 ASP.NET Core 到 Json.NET 的依赖。 今天,ASP.NET Core 依赖于 Json.NET。 虽然这提供了 ASP.NET Core 和 Json.NET 之间的紧密集成,但这也意味着应用程序开发人员无法自由选择他们使用的 JSON 库。 这对于 Json.NET 的客户来说也是一个问题,因为版本是由底层平台决定的。 但是,Json.NET 经常更新,应用程序开发人员经常希望——甚至不得不——使用特定版本。 因此,我们希望移除 ASP.NET Core 3.0 对 Json.NET 的依赖,以便客户可以选择使用哪个版本,而不必担心他们可能会意外破坏底层平台。 此外,这也使得插入一个完全不同的 JSON 库成为可能。

  • 为 Json.NET 提供 ASP.NET Core 集成包。 Json.NET 已经基本成为.NET 中JSON 处理的瑞士军刀。 它提供了许多选项和工具,允许客户轻松处理他们的 JSON 需求。 我们不想妥协客户今天获得的 Json.NET 支持,例如,通过AddJsonOptions扩展方法配置 JSON 序列化的能力。 因此,我们希望将 Json.NET 集成作为 NuGet 包提供,开发人员可以选择安装该包,以便他们获得今天从 Json.NET 获得的所有功能。 此工作项的另一部分是确保我们拥有正确的扩展点,以便其他方可以为他们选择的 JSON 库提供类似的集成包。

以下是有关此计划的更多详细信息。

对高性能 JSON API 的需求

自 .NET Core 出现以来,对 .NET 堆栈的要求发生了一些变化。 从历史上看,.NET 重视可用性和便利性。 在 .NET Core 中,我们更加关注性能,并进行了大量投资以满足高性能需求。 我们在流行的 TechEmpower 基准测试中改进证明了这一点。

在 .NET Core 2.1 中,我们添加了一个名为Span\ 的全新原语这允许我们以统一的方式表示本机内存和数组。 对于这种类型,我们还添加了一组解析和编码 API,它们的内存效率更高,而不必求助于不安全的代码。

最小化分配的部分工作是避免纯粹出于解析原因将 UTF-8 有效负载转码为 UTF-16 字符串。 目前,Json.NET 是通过读取 UTF-16 来实现的。 我们需要能够直接以 UTF-8 读取(和写入)JSON 文档,因为大多数网络协议(包括 HTTP)都使用 UTF-8。

在 .NET Core 2.1 中,我们了解到更新现有 API 以利用Span<T>有限制的。 虽然我们确实添加了一堆接受跨度的重载,但我们还必须生成全新的 API,这些 API 围绕最小化分配和处理缓冲区而设计,我们在System.Buffers命名空间中公开了这些 API。 在System.IO.Pipelines我们还添加了一个编程模型,使开发人员无需处理生命周期问题即可共享缓冲区。

基于这些经验,我们认为为了支持 JSON 解析,我们需要公开一组新的 JSON API,这些 API 专门针对高性能场景。

您可能想知道为什么我们不能只更新 Json.NET 以包含对使用Span<T>解析 JSON 的支持? 好吧,Json.NET 的作者 James Newton-King 对此有以下看法:

Json.NET 是在 10 多年前创建的,从那时起,它添加了广泛的功能,旨在帮助开发人员在 .NET 中使用 JSON。 在那个时候,Json.NET 也成为了 NuGet 最依赖和下载的包,并且是 .NET 中 JSON 支持的首选库。 不幸的是,Json.NET 的丰富功能和流行程度不利于对其进行重大更改。 支持像Span<T>这样的新技术需要对库进行根本性的重大更改,并且会破坏依赖它的现有应用程序和库。

展望未来,Json.NET 将继续致力于和投资,既解决当今的已知问题,又支持未来的新平台。 Json.NET 一直与 .NET 的其他 JSON 库一起存在,并且不会阻止您一起使用一个或多个,具体取决于您是需要新 JSON API 的性能还是 Json.NET 的大型功能集。

将 Json.NET 集成移动到单独的 NuGet 包中

今天,没有 Json.NET 就不能使用 ASP.NET Core,因为它是 ASP.NET Core 本身的依赖项。 多年来,我们收到反馈称,该依赖项可能与其他依赖于不同版本 Json.NET 的库发生冲突。 过去,我们曾考虑通过在 ASP.NET 中使用 Json.NET 的私有副本来解决此问题。 但是,当开发人员想要配置 Json.NET(例如,为了控制序列化器在格式化 JSON 对象时的行为方式)时,这会产生问题。

展望未来,我们希望:

  1. 将 ASP.NET Core 中 Json.NET 的内部使用替换为平台提供的新 JSON API。

  2. 将 Json.NET 的面向公众的使用纳入一个可选的集成包中,该集成包可以从 NuGet 获取。

因此,将继续支持 ASP.NET Core 和 Json.NET 之间的现有集成,但将移出平台并进入单独的包。 但是,由于该集成随后被设计为位于平台之上,因此它还允许客户将 Json.NET 更新到更高版本。

此外,需要更高性能的客户也可以选择使用新的 JSON API,但要牺牲 Json.NET 提供的丰富功能集。

area-Meta

最有用的评论

假设这个新的解析器将用于所有内置的 JSON 内容,如appSettings.json ,我可以提早请求支持评论吗?

谢谢。

所有193条评论

这很棒。 我完全赞成更快,更少地分配 json 解析。

是否会讨论新的 json apis 将支持的来自 json.net 的功能? 如果有的话,我认为我想到的两个主要功能是重命名/外壳属性和忽略空属性。

是否会讨论新的 json apis 将支持的来自 json.net 的功能?

是的。 我们已经做了一些早期的想法,我们将迁移到 CoreFx。 这将是一个像往常一样在开放环境中设计和构建的功能。 此外,我已经联系了许多流行 JSON 库的作者,并邀请他们审阅本公告的早期草稿。 我希望我们可以共同努力为平台创建一个可靠的 JSON 组件,同时保持其上的生态系统(例如 ASP.NET Core)可插入以允许其他人使用。 最后,不同的消费者会有不同的目标,并且能够插入不同的库意味着您可以在选择对您的应用程序具有最佳成本/收益的组件时获得最大的灵活性。

嘿@terrajobst。 新的 JSON 会作为网络标准 API 表面出现,还是暂时集成到 Core 中?

嘿@terrajobst。 新的 JSON 会作为网络标准 API 表面出现,还是暂时集成到 Core 中?

是的,问题只是它可以赶上哪个发布列车。 2.1 可能太早了。

因此,框架中的 JSON 解析位计划在 v3.0 进入 RTM 时可用,或者只有 ASP.NET Core 中的集成 API 是完整的(只有一个实现 - JSON.NET),可以在以后约会?

3.0的计划如下:

  1. 内置高性能 JSON API。 低级读取器/写入器、基于Stream的读取器/写入器和序列化器。
  2. ASP.NET Core 可插入 JSON 组件。

有一个开放式问题,即 3.0 中的 ASP.NET 模板将使用什么。 根据我们在 3.0 中可以提供的保真度,我们可能会让它们包含在 Json.NET 集成包中。 然而,我们的目标是提供足够的保真度和奇偶校验,默认情况下仅依赖于内置的。

谢谢 - 这有助于解决问题。 👍

还有一些额外的问题!

如果使用集成包,它是在整个 ASP.NET Core 管道中使用还是仅在某些地方使用?
我假设 Kestrel 将始终使用内部读取器/写入器。

Api 人体工程学会是:

  • 仅当您想要增强内置功能集时才提供集成。
  • 总是提供一个集成包,但一个是内置的,将低级读取器/写入器集成到更高级别的功能中。

假设这个新的解析器将用于所有内置的 JSON 内容,如appSettings.json ,我可以提早请求支持评论吗?

谢谢。

这是一个很棒的消息! 快速提问:这个库将依赖哪些包?

为什么要重新发明一个经过生产客户测试的轮子? 如果 Json.Net 有问题,只需发送 PR,因为它是开源的。

我想 Json.NET 的问题在于它不归 Microsoft 所有,因此必须更换它。 哦,但是 System.Runtime.Serialization 中已经有一个,称为 DataContractJsonSerializer。 您可以使用它,还是编写新的 API、DIY 代码很有趣,以至于无法避免?

我对此不太满意的原因是 Json.Net 已经支持边缘情况,例如 F# Discriminated Unions。 不是特别好,但在开发人员可以接受的水平上。 相反,除了 ASP.NET 网站的用例之外,任何新 API 通常都会忘记任何其他内容。

@markrendle

@Thorium你真的读过 OP 吗? 它解释了为什么不是 JSON.NET,并且 JSON.NET 将继续受到外接程序包的正式支持。

@JamesNK 😄

@Thorium Json.NET 不会消失。 你不会失去任何东西。 这是简单和高性能场景的另一种选择。

@Thorium Json.NET 不会消失。 你不会失去任何东西。 这是简单和高性能场景的另一种选择。

生成的 Json 将如何向后兼容?

例如,我正在使用 SignalR,它在后台使用 Json.NET。 现在,我的 F# 区分联合是否会序列化为类似的结构,以便我不会因为新的 Azure Signalr 服务(背板)抛出运行时异常而解决问题,因为序列化结构与服务器当前的 SignalR 库不同?

我希望其他人能快速掌握新的 API。 看着你, @AzureCosmosDB ;-)

您是否计划包含像 JObject 这样的类并支持动态,或者这超出了此功能的范围?

我建议查看以下库之一:

这可能是获得灵感的好方法。

DataContractJsonSerializer在内部使用这个新的读写器吗?

我已经联系了许多流行 JSON 库的作者,并邀请他们审阅本公告的早期草稿。 我希望我们可以共同努力为平台创建一个可靠的 JSON 组件,同时保持其上的生态系统(例如 ASP.NET Core)可插入以允许其他人使用。

继 JSON.NET 之后的第二个最受欢迎的 JSON 库 - ServiceStack.Text已经被重构以构建在 Span 上,这有什么原因吗?蜜蜂被排除了? ServiceStack.Text 序列化器用于为 ServiceStack 提供动力,ServiceStack 是最流行的“替代 .NET Core 兼容 Web 框架”之一,支持在 .NET 中的更多平台上运行。 我很好奇您指的是哪个“生态系统”并希望与这里“合作”? 我显然对这些“可插拔”API 最终的兼容性如何,或者这是否最终成为采用和集成新 MS 库最终扼杀它正在取代的生态系统的另一个领域感兴趣。

可能值得回顾一下 MIT 许可的高性能https://github.com/neuecc/Utf8Json

这绝对是我们需要的......我对主类名称的建议,只需使用“ Json ”。

@terrajobst我想知道这什么时候会发生......

我一直想知道为什么 JSON.Net 被添加为直接依赖项而不是抽象(即使考虑到它是 .Net 生态系统的事实上的 JSON 包)。

但是,我认为为 JSON-only 添加抽象在某种程度上是一种尝试。 我认为像我们在奥尔良 IExternalSerializer中使用的 _serializer_ 抽象形式为Microsoft.Extensions.Serialization或其他东西会更有效......

有什么特别的原因为什么 make 是 JSON-only? 我看到其他情况下人们可以插入其他类型的序列化程序......

@galvesribeiro类似IOutputFormatter / IInputFormatter

@yaakov-h 不知道这些......是吗?

@galvesribeiro AspNetCore: https : //docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.formatters.iinputformatter ? view = aspnetcore-2.1

好吧……现在说得通了。 那么这个 _new_ 仅限 JSON 的抽象在哪里发挥作用呢?

开始这项工作的决定也证明了 System.String (UTF-16 String) 的低效率。
我认为,如果您首先处理创建 utf-8 字符串 BaseType 的任务,那么新的 JSON 挂钩将抽象出 asp.net 和 json 库之间的所有 json 处理,看起来会好得多。
--> 也许创建一个 System.Utf8String

是的...我记得@migueldeicaza不久前说有一天,他会让 .Net 使用utf8字符串😄

@jges42 @galvesribeiro添加https://github.com/dotnet/corefx/issues/30503。 似乎它也计划用于 .Net Core 3.0。

这些新的 JSON API 是否具有用于Utf8Stringchar / string专用代码路径,或者优化是否涉及改变现状,以便所有不是 UTF-8 的内容将不得不转码到它吗? (这不一定涉及巨大的成本,因为几乎没有任何东西是string的原生UCS-2 UTF-16 并且仍然需要进行调整/考虑,我只是想了解API 表面。这样做是为了让 Kestrel 更有效率;我只是希望设计比 Kestrel 考虑更多的客户端。)

@galvesribeiro
事实上,我认为你提出了一个很好的观点。 我认为创建一个高效的序列化框架和一个高效的 Json 解码器/编码器是两类问题。 我知道有一些方法可以将结构标记为可序列化,但我从未见过它用于任何 Json 序列化。

Rust 的 Serde 项目实际上有一个很好的概念,将问题拆分为 2 个问题:

  1. 序列化/反序列化(特征类似于 C# 中的接口),这意味着从该接口继承的任何类型都可以序列化/反序列化
  2. Serializer/Deserializer 是特定于格式的实现。

类型可以手动实现序列化/反序列化,也可以通过宏(可以被视为某种形式的编译器插件)来生成执行实现这些特征所需的代码。 如果一个类型包含一个没有实现这些特征的子类型,它甚至会在编译时发出警告。 总体而言,这是一个不错的概念,因为这意味着您只需编写一些数据对象并将其(反)序列化为任何支持的格式。 通过这种方式编写格式要容易得多。

我不认为 Serde 的方法都适用于 C#,因为它并没有真正提供任何类型特定的属性,这些属性对于某些数据结构可能很重要。 所以必须为此做一些工作。 还考虑到 AoT 编译对于某些项目(WASM)非常重要,它也应该与它一起运行。

这是一个指向 Serde 文档的链接,以使其更加清晰(单击底部的 4 个特征以查看概念):
https://docs.serde.rs

@mythz ServiceStack.Text 的许可证是 AGPL,但有一些 FOSS 例外——它可能会阻止人们在专有软件中使用它。 此外,我认为微软员工甚至需要获得法律许可才能接触它,任何查看过源代码的员工都可能被禁止使用任何其他 JSON 库或相关技术。

@poizan42 ServiceStack.Text 拥有 OSS/商业许可证双重许可,可在 OSS 和闭源商业项目中免费使用。 但是源代码许可证无关紧要,因为 MS 正在开发自己的实现。

断言是 MS 正在与“生态系统”合作开发“可插入的”JSON 序列化器 API——如果 ServiceStack 近十年来一直在积极开发,它是少数几个能够维持它的独立 .NET 软件套件之一在其生命周期内拥有除 MS 之外的独立健康社区,它保持着仅次于 JSON.NET 的第二大最受欢迎的 JSON 序列化程序,以及似乎是第二大流行的积极开发的 Web 框架(MS 之外),它在比任何 MS 都多的平台上运行Web 框架不被视为主要受这些变化影响的“生态系统”的一部分,我很好奇它们指的是什么“生态系统”,为什么我们被排除在外,还有多少人被排除在外,因为它们是不被视为“生态系统”的一部分。

我不明白这一切的怨恨。 Asp.net 强制您使用特定版本的 json.net。 他们正在改变它,所以你可以选择你想要的任何 JSON 解析器(或混合它),并且有一个默认的 OOB。 ServiceStack 应该对这一变化感到高兴,并对这一发展进行监控并提供反馈,而不是抱怨它是如何被忽视的,这很少是培养良好社区精神的有效方式。 我个人认识许多 .net 团队成员,我相信他们没有恶意。 他们都是 OSS 和社区工作的大力支持者。
就个人而言,任何 GPL 衍生许可证对我来说都是一个很大的自动否决权。 Apache 或 MIT 适合我和我的客户,否则我们将继续前进。 没有神秘的双重许可证。

Asp.net 强制您使用特定版本的 json.net

不。 为何如此?

我不明白这一切的怨恨。

借调!

我个人很高兴我们最终能够使用我们选择的序列化程序,而不必下载 JSON.Net 只是为了不使用它,但仍然需要发布它,因为 ASP.Net 对库有一个硬引用。

(无耻的插件:https://github.com/gregsdennis/Manatee.Json)

@dotMorten

我不明白这一切的怨恨。

因为你要么没有阅读,要么没有理解我的评论。 尝试直接回应我的评论(即使用引用功能),而不是编造你自己的叙述。

他们正在改变它,所以你可以选择你想要的任何 JSON 解析器(或混合它)

所以就像一个神奇的“混合”,他们会自动选择最优化的 API 和可插入性选项,现有的 .NET 序列化程序将能够直接插入/输出并混合到其内部可定制性选项中,而线格式正是相同并且一切都将在所有序列化程序中工作? 在这种情况下,您是对的,在 API 固化之前不需要协作或集成测试。 或者,序列化程序的实现可能会因各种差异和意见而更加细微,并且一切都不会正常工作,并非所有自定义选项都将完全实现,线格式不会相同并且不可能实现不同实现之间的完美互操作。 您所掩盖的“可插入性”产生了很大的不同,它可以决定我们必须进行多少重写,以及是否可以支持现有的和这个新的实现。

ServiceStack 应该对这个变化感到高兴,并监控和提供关于这个发展的反馈,

我们没有机会去做(或仍然知道该怎么做),但感谢你让我知道我应该有什么感受。 我更愿意先评估库的功能、互操作性和兼容性,然后才能评估每个库的强度。 也许它会很棒并且很容易支持这两种实现,但是从与不同序列化器实现互操作的经验来看,它充满了不兼容性和极端情况,并且依赖于不同的特定于序列化的实现和功能。 我的预测是 JSON.NET 和默认 impl 之间的互操作会很棒,因为这是他们的设计目标和正在测试的内容,但其他序列化程序不会那么幸运。

而不是抱怨它是如何被忽视的,这很少是培养良好社区精神的有效方法。

我质疑他们的断言,即他们是与“生态系统”合作开发的,.NET 有过每次捆绑“默认”库时都会杀死现有生态系统的历史,我也期待这种情况会发生在这里(我正在努力回忆捆绑默认值曾经帮助过生态系统的时间)。 但无论如何,我们需要开发与他们发布的任何内容的无缝集成,我希望能够在 API 冻结之前访问和输入这些内容。 但是没关系,我不希望您关心它如何影响需要支持现有和未来实现的现有框架/库,您可能只关心 JSON.NET 是否仍然受支持,因为这就是影响您的全部,但是试着坚持你的假设,让我们知道我们应该如何吸收这样的破坏性变化。

我很难回忆起捆绑默认值曾经帮助过生态系统的时间

哦,来吧!

(其余的我基本同意你的观点)

@mythz我很惊讶这会导致任何问题,因为我们今天将另一个 3rd 方 JSON 库捆绑到框架中。 我们将 JSON 放入的地方屈指可数,而且大多数地方都有用户可以合理替换的提供程序模型(如 MVC 格式化程序)。

我的预测是 JSON.NET 和默认 impl 之间的互操作会很棒,因为这是他们的设计目标和正在测试的内容,但其他序列化程序不会那么幸运。

我已经可以告诉您,我们将发布的内容不支持 JSON.NET 支持的所有功能。 所以这已经不是真的,事实上,我们预计它在某些情况下的能力会降低(由于性能和范围的原因)。

可插拔性今天基本上已经存在,我们到处都有默认的 JSON.NET 实现。 这只是将默认值更改为新的 JSON 序列化程序......

@abatishchev

我真的想不起来了,什么时候在他们的基础框架(或项目)中嵌入或采用默认实现有利于现有的周围生态系统? 每次我看到它捆绑在一起,例如 NuGet、MVC、ORM、单元测试、Web API 等,它只会产生不利影响,有效地消耗氧气和动力在该领域内进行竞争。

有时候像 ASP.NET Ajax 这样的竞争库在竞争中失败了,他们最终放弃了它并采用了 jQuery,但我不记得它曾经有过帮助的时候吗? 注意:这只是我几年后密切关注 .NET 的观察,也许有一些例子,我很想知道一些? 但从我的 POV 来看,MS 默认值的影响对其正在取代的现有功能生态系统产生不利影响。

@mythz用户从 Microsoft 获得默认解决方案的好处与替代解决方案作者的好处不同。 EF 是 .NET 世界中最好的 ORM,而 MSTest 在当时比 NUnit 更好。 在我看来。

但是,让我们不要泛滥并坚持主题。 干杯!

@davidfowl这只是将默认值更改为新的 JSON 序列化程序......

我想建议没有默认的序列化程序,并要求下载一个实现。 如果必须有一个默认值,它是否会被烘焙到框架或某个单独的库中(就像目前的情况一样)?

我想建议没有默认的序列化程序,并要求下载一个实现。 如果必须有一个默认值,它是否会被烘焙到框架或某个单独的库中(就像目前的情况一样)?

这是不合理的,因为体验会很差。 每个现代平台都内置了 JSON。

@davidfowl现在不会造成问题,因为它尚未发布,但我们仍然需要评估它将造成的中断和工作范围。 无缝支持它需要付出多少努力,我们是否能够将自定义应用到新的 impl 以支持我们现有的行为,我们是否能够支持新的自定义模型和 API,我们是否能够自定义我们的序列化程序以支持默认配置/线格式将使新 API 能够同时支持 .NET Core 和 .NET Framework - 虽然很明显 ASP.NET Core 3 将放弃 .NET Framework,但尚不清楚新 API 是否将使用 .NET Framework。 NET Core only 类型将阻止我们继续支持 .NET Core 和 .NET Framework。

我已经可以告诉您,我们将发布的内容不支持 JSON.NET 支持的所有功能。 所以这已经不是真的,事实上,我们预计它在某些情况下的能力会降低(由于性能和范围的原因)。

我只希望它支持 JSON.NET 功能的一个子集,例如 JSON.NET 会支持默认的线格式吗? (我假设是)。 新的 impl 是否会在可能的情况下采用 JSON.NET 序列化格式(也假设是)。

无缝支持它需要付出多少努力,我们是否能够将自定义应用到新的 impl 以支持我们现有的行为,我们是否能够支持新的自定义模型和 API,我们是否能够自定义我们的序列化程序以支持默认配置/线格式将使新 API 能够同时支持 .NET Core 和 .NET Framework。

@mythz我没有关注其中的一些内容。 我试图弄清楚讨论现有的 API 与它们将如何被使用之间有多少关系。 也许我们可以看看一些具体的场景?

@mythz我对 servicestack 唯一真正担心的是,如果 .net framework classic 不支持这个新的 api,那么 servicestack 将无法同时支持 .net core 和 .net classic,作为客户,包取决于这些库在 .net framework full 中将不可用。 那是你关心的吗? 我问是因为你作为一个具体例子的关注并不明确。

这也是一个处于初始阶段的提案,它想要实现的目标看起来很有希望。 建设性的批评总是对任何 oss 项目都有好处。

@mythz用户从 Microsoft 获得默认解决方案的好处与替代解决方案作者的好处不同。

通过生态系统,我指的是周围的 .NET 库生态系统/社区(大概也是 OP 中所指的“生态系统”),它取代了它,我还认为 .NET 用户也可以从健康的生态系统中受益多种选择和更多竞争(Python、Java、Node、Ruby、PHP 等更健康的生态系统的特征也是如此)。

EF 是 .NET 世界中最好的 ORM

EF 发布后不久,它迅速占据了大部分 ORM 市场份额,同时比 NHibernate 慢 6 倍以上,同时可以说支持的功能较少,摘自我2012 年的 InfoQ 采访

他们对实体框架中 ORM 数据访问层的最新尝试也对早期著名的 ORM NHibernate 曾经繁荣的社区产生了负面影响。 尽管比其他所有开源 .NET ORM 慢几倍,但 EF 成功地吸引了比所有其他 ORM 总和还要多的下载量。

请记住,这是在 .NET Core 之前,性能现在是重中之重,但它是 MS 默认对现有生态系统/社区造成不利影响的一个历史例子。 IMO 几乎可以接受当 MS 引入默认值时现有社区发生的情况,这就是为什么最近有人推迟恢复与 IdentityServer 和 AutoMapper 竞争的默认值。

并且 MSTest 在当时比 NUnit 更好。

IMO 从来都不是(而且 R# 对 NUnit 的支持一直是出色的 AFAICR),而且我们无法在 Mono 上跨平台运行它的事实意味着在 Mono 上支持跨平台的库(在 .NET Core 之前)无法使用它。

但是,让我们不要泛滥并坚持主题。 干杯!

我也不想在这个问题上劫持这个线程,但需要说明为什么我不同意你的观点。

与此相关,现在使用与 JSON.NET 不同的序列化程序的主要原因是性能,考虑到这个新的默认序列化程序的原因是性能。 由于大多数人只使用默认值,我预计这会对 JSON.NET 共享产生最显着的影响,而使用替代序列化程序的主要原因应该不再存在于这个更快的实现中。 所以基本上我也看到这对现有(图书馆)生态系统产生不利影响。 IMO 较弱的 JSON 库生态系统对 .NET 来说是一个净负面因素(大多数消费者不会看到他们只会使用默认值而忘记其他选项),但这不是我主要关心的问题。

@davidfowl @shahid-pk

尽管如此,我实际上更喜欢它在 8 年前存在,因为开发 ServiceStack.Text 的主要原因是因为 .NET Framework JSON 序列化程序非常慢。 但这次毕竟SS.Text已经扩展了许多的所有功能,我们的图书馆,支持自定义如不同语言ServiceStack支架,不同的ServiceStack JSON的自定义选项,在JSON支持ServiceStack模板,在复杂类型JSON BLOB支持ServiceStack .Redis

所以现在我专注于评估影响会是什么,新的 API 和可插入性选项会是什么样子,我们是否可以在其上改进现有功能,我们是否能够在 SS .NET Core Apps 中作为 JSON 序列化程序采用(它会破坏什么),ServiceStack.Text 是否能够支持新的 API,我们是否能够支持 .NET v4.5,是否能够对其进行自定义以支持现有部署的线格式等。我由于我还没有机会使用或看到任何东西,因此基本上不知道对这方面的任何影响或将要进行的策略。 当我有机会使用它时,我会知道更多答案,而且我显然希望有机会在 API 被冻结之前测试集成并提供反馈和提出更改建议。

@mythz

是否有理由排除在 JSON.NET 之后第二个最受欢迎的 JSON 库 - ServiceStack.Text已经被重构以构建在 Span API上?

遗漏不是故意的。 作为CoreFxLab 存储库的一部分,我们积极搜索并与 JSON 库作者合作,我们的一位开发人员开始根据他们的工作对我们的工作进行基准测试。 我相信该列表最初是通过在 NuGet 上使用

我很好奇您指的是哪个“生态系统”并希望与这里“合作”?

.NET 生态系统,尤其是对 JSON 处理感兴趣的各方。

我显然对这些“可插拔”API 最终的兼容性如何,或者这是否最终成为采用和集成新 MS 库最终扼杀它正在取代的生态系统的另一个领域感兴趣。

计划中的 ASP.NET Core 扩展点的目的是使客户能够用他们想要的任何 JSON 库替换内置的 JSON 组件。 当然,ASP.NET 始终附带“包含电池”,即合理的默认体验。 过去这一直是 Json.NET 并且向前发展它是一个平台提供的组件。 考虑到 Json.NET 与 ASP.NET 有点硬连接,新计划对于像你这样的人来说似乎更好; 所以我不完全确定你认为我们计划的哪一部分是威胁。

有一个开放式问题,即 3.0 中的 ASP.NET 模板将使用什么。

模板不是模块化的时候吗? 以 vue.js 为例。

image

创建一个新的 vue 应用程序可以让你选择你想要的东西。 为什么不能对asp.net 做类似的事情,而不是创建500 个模板来满足所有场景。

以下是 .ASP NET Core 2.2 中某个功能的具体示例,其中非 JSON.NET JSON 输入/输出格式化程序将面临问题以及解耦解决方案如何提供帮助:
问题详细信息功能,允许RFC 7807兼容的错误响应:
https://github.com/aspnet/Mvc/blob/release/2.2/src/Microsoft.AspNetCore.Mvc.Core/ProblemDetails.cs

[JsonProperty(NullValueHandling = NullValueHandling.Ignore, PropertyName = "instance")]
public string Instance { get; set; }

[JsonExtensionData]
public IDictionary<string, object> Extensions { get; } = new Dictionary<string, object>(StringComparer.Ordinal);

上面的代码标注了 JSON.NET 特定的属性,包括一个特定的回退属性[JsonExtensionData] ,所有未知的 JSON 属性都反序列化到这个字典中,这个字典的内容被序列化成正常的 JSON 结构。

任何替代的 JSON 输入/输出格式化程序现在都需要处理这些 JSON.NET 特定属性,以便能够正确地序列化/反序列化此类型或找到不同的方式,即这些类型回退到 JSON.NET。

现在,如果我们有一个明确定义的功能规范,JSON 的 Input/OutputFormatter 需要支持 3.0,则上述问题不存在,因为这些属性可以存在于 Microsoft.Extension... 包和每个自定义 JSON Formatter 中可以使用它们来实现此功能以兼容。

据我所知,ASP.NET Core 中只有少数“官方”源代码实例用 JSON.NET 属性注释,但我也看到第三方库使用 JSON.NET 特定属性(通常用于指定属性名称通过[JsonProperty("name")]

FWIW,这就是https://github.com/Tornhoof/SpanJson/issues/63的内容。

@terrajobst我想你在阅读我之前的评论之前已经回答了,IMO 澄清了我更多的担忧。

我们正在积极寻找其他反馈。

在哪里? 是否有 API 提案/文档,是否创建了 API,它是在哪个 repo 下开发的?

我想你在阅读我之前的评论之前就回答了,IMO 澄清了我更多的担忧。

我读过它,但您似乎反对任何默认设置,正如@davidfowl 所解释的那样,这对我们来说是不切实际的。 我的观点是,我们的计划是对我们目前所拥有的进行改进,即实际上硬连接到 Json.NET。 因此我的问题。

在哪里? 是否有 API 提案/文档,是否创建了 API,它是在哪个 repo 下开发的?

我们故意没有在 .NET Core 中进行任何编码/API 设计,因为我们想先发布这个公告。 我们不希望人们在没有提供此公告提供的上下文的情况下阅读茶叶。 换句话说,请继续关注,我们将很快发布 API 和代码。

@terrajobst对帖子的整体印象

  1. 做出改变的决定已经完成。

展望未来,我们计划对 JSON 支持进行一些更改:

  1. 一些初步设计已经完成
    我们需要高性能的 JSON API。
    移除 ASP.NET Core 对 Json.NET 的依赖。
    为 Json.NET 提供 ASP.NET Core 集成包。

这一切都意味着方向已定。 “生态系统”所要求的只是找到 MS 无法实际解决的明显痛点。

省略 ServiceStack 并将其作为一些二级 .NET 库来讨论是可笑的。 即使我只使用 MS 提供的库,这并不意味着我不知道替代方案。

我对 MS 做出决定没有任何问题,但如果它是直接陈述的,并且没有涵盖关于已经做出的决定的“社区反馈”。

这是我的印象

@terrajobst

我读过它,但似乎你反对有任何默认

从来没有建议过,在此之前 JSON.NET 已经是默认设置了。 我已经在上面进行了更详细的解释,但重申这将取代默认值并成为新的事实上的标准,其中 .NET Core 在其未来实际上将只有 2 个 JSON 序列化程序:这个新的事实上的高性能默认值和 JSON。 NET 的自定义功能。 其他 JSON 序列化程序将成为利基市场,例如添加独特的功能以支持不同的场景。

我们故意没有对 .NET Core 进行任何编码/API 设计,因为我们想先得到这个公告。

好的,所以任何“局外人”都不可能知道可插拔性、可扩展性或互操作性有多好
还会。

我们不希望人们在没有提供此公告提供的上下文的情况下阅读茶叶。 换句话说,请继续关注,我们将很快发布 API 和代码。

那么它是内部开发的吗? 在你发布之后多久,外部人员必须测试并提出对 API 设计的更改? 我主要关心“可插入”和“可扩展”API 的外观,我们是否能够“接管”并完全控制 Ref/Value 类型的连线格式? 内置类型、枚举、布尔值、其他内在函数等呢? 例如,它可以配置bool以接受其他流行的 JSON 值,如“yes”、“on”、“1”。

其他问题:

  • 此实现是否可以独立使用(在单独的 NuGet 包中)?
  • API 的“可插入”部分是绑定到 Web 框架还是可以在其他地方使用(例如 Xamarin/UWP)
  • 它会支持 .NET Standard 2.0 还是 .NET v4.5?
  • 如果没有,API 是否能够支持 .NET Standard 2.0 或 .NET v4.5?

@mythz
它并不是真正的内部开发(据我所知),Reader/Writer 部分是在 corefxlab 中完成的(https://github.com/dotnet/corefxlab/tree/master/src/System.Text.JsonLab/System/Text/ Json),特别是在 corefxlab 中还没有高级 API。

就我个人而言,除了可扩展/可插拔 API 部分之外,我希望 .NET 标准(即属性等)。 corefxlab 中的库目前是 .NET Standard 1.1,但我想这会根据库的性能目标等而改变。

@mythz

您似乎急于接受我的陈述并将它们置于“玻璃杯半空”的语境中。 我明白了,你很怀疑。 我建议我们为自己节省大量按键并讨论具体的 API 建议,而不是抽象地讨论它们。 我相当相信我们的计划将提供您需要的扩展点。

@terrajobst不要怀疑,而是想知道我假设已经确定的高级建议功能是什么(或者它们是否仍然待定?)。 这个公告是我们大多数人第一次听说它,所以我在对它的可插入性、可扩展性和可重用性进行了一些澄清之后。 System.Text.JsonLab是当前的实现吗? 这是否意味着它也将支持 .NET Standard 2.0 和 .NET v4.5?

对于库创建者来说,这可能是一个不错的功能,但您也必须考虑企业开发人员使用 50 个带有依赖树的库并试图找到它们之间的兼容性。 是否会有绑定重定向样式的映射配置来尝试管理不匹配?

这场谈话似乎很紧张,无论是因为人们以某种​​方式受到冒犯,还是因为他们试图为已采取或未采取的行动辩护。 很难读。 周围道歉! 请保持当前状态并继续前进。

这种变化似乎有两个原因。 首先是希望利用 .Net Core 中的新类型提高性能。

此外,人们认识到,在某个时候,由于包含对 JSON.Net 的硬引用而导致架构错误,JSON.Net 是一个驻留在 .Net 外部的库。 为了解决这个问题,必须引入一个新的内置 JSON 实现以及允许第三方使用他们自己的实现的接口。

这会破坏东西吗? 是的! 这就是为什么公告上有“重大变更”标签的原因。 (也许该标签应该在这里复制。)而且由于已知这是一个重大更改,因此开始讨论以探讨其影响。 此外,为了尽量减少影响,将提供一个额外的库,允许人们继续使用 JSON.Net。

作为图书馆作者,我对此非常感兴趣,我更希望对话向前推进。


@Tornhoof回应你的例子,如果我想继续使用 JSON.Net,我还需要参考我之前提到的兼容性库。 它应该主要是即插即用的,但可能会有变化。 我绝对希望框架 (.Net Core) 规定我选择的序列化程序必须使用这些属性进行序列化,尤其是当我的序列化程序对类似概念使用不同的机制时。

.Net 提供的解决方案应该比这更通用。 特定的模型序列化处理应由所选的 JSON 实现执行。

@mythz从我所知道的和从参与制定此提案的人员那里看到的一切来看,您将有很长的机会在所提议的 API 和实现稳定发布之前对其进行审查和评论。 在如此早的阶段发表这篇文章的目的之一就是为了找到像你这样的人。

@gregsdennis
我不确定你说的更通用是什么意思?
假设您的序列化程序具有覆盖 json 属性名称、更改其空行为和/或回退/捕获所有实现的概念,并假设所有三个功能都是 .net core 3.0 的 JSON 序列化程序共享规范的一部分,那么实现包将这些属性映射到您的内部实现细节。
例如,如果您的库更喜欢使用[DataMember]来指定属性的名称(就像 SpanJson 那样),您的集成包应该很容易映射。
我并不是说属性是正确的方式,它只是代码示例的可见部分。

显然,理想的世界是没有 ASP.NET Core 框架库会使用任何特定的注释来控制序列化行为,但是对于上面的那个功能,这非常复杂甚至不可能,因为 RFC 要求遵循某些命名规则.

无论哪种方式,我认为未来都会有很多关于这些共享功能的讨论,如何使用和描述它们。

有没有计划在新的 JSON 解析器中使用 SIMD 指令,比如在 RapidJSON 中?

参考: http :

提议的建议看起来不错,但请尝试消除“破坏性更改”我只是 3rd 方库的一般用户,最近有这样的经历之一,反射突然被排除在 UWP .net 本地发布构建过程(编译器)之外)。

因此,几个月内我的所有 UWP 应用程序都无法在发布模式下构建,因为我不得不重写所有在 3rd 方库中使用反射的代码。 我知道许多库作者不得不再次拆分他们的实现以排除那些 UWP 部分中的反射。 大多数图书馆作者没有参加聚会,我被迫跳槽。 尽管 MS 脱颖而出并致力于在 .net 标准 2.1 中实现替代方案。 我们知道,实际情况是 .net 标准 2.1 从最初的突破性更改开始需要数月时间才能交付。

要点很简单,这对我来说是一个极具破坏性的过程,对最终用户产生了巨大的影响,而且绝不是“平稳”和无摩擦的。

这绝对是正确的步骤。
我想知道一段时间看到这个 Json.Net 参考。

@Tornhoof我认为需要有一个明确的分离:每个提供者需要实现的接口才能与 .Net Core 3.0 一起使用,以及内置的默认实现。

接口应尽可能通用。 也许就像只定义Serialize()Deserialize()方法一样简单。

其他细节应该留给实现。 如果默认实现使用一个属性来定义自定义属性键控机制,我可以接受。 我认为这是一个特定于实现的细节,不应成为接口的一部分。

也就是说,具有自定义键属性的能力可能是一项要求,尽管我不确定如何将其编码。

@gregsdennis是的,你是对的,我主要看的是 IInput/OutputFormatter,它目前已经存在于 ASP.NET Core 中,特别是关于用非 JSON.NET 版本替换它们的问题。
无论如何,正如您和@mythz 的评论所显示的那样,我想范围定义会变得有趣并且可能没有那么简单(我记得 DI 接口规范的问题)。 因此,最好在流程的早期让许多不同的观点参与进来。

@Tornhoof同意。 目前格式化界面明显JSON.Net为主,但没有这么多的串行器本身,而是在选择对象。 似乎我们还需要一种通用的方式来传达选项(一个通用的选项对象)。

这是否意味着选项对象规定了实现的最小功能集? 我不认为它。 我最近为我的序列化程序实现了一个格式化程序,它完全忽略了选项对象,但它是供我私人使用的。 如果我想制作一个供公众使用,我会考虑尝试尽可能多地解释这些选项以支持它们。

这不是我们现在做事的方式。 这些选项是特定于序列化程序的,它们没有通用接口。 MVC 中的格式化程序已经被适当地分解出来并且没有耦合到任何东西。 JsonResult 将有重大更改,因为它直接采用 JsonSerializationOptions(JSON.NET 类型)。

我正要说同样的话。 我们不打算为 JSON 读取器/写入器/序列化器构建抽象。 不需要; 框架要么处理 IO 原语(例如StreamTextReader ),要么插入更高级别的框架处理(例如 ASP.NET Core 格式化程序)。

说到痛点:就我个人而言(我可能是极少数),我担心许多 JSON 解析器的松散性质。 有一个标准 (tm),但大多数解析器选择宽容并接受不合格的文档。 从长远来看,这样做的坏处是开发人员不会按照他们对库实施的标准来实施。 如果库允许不合格的文档,只要所有位都使用相同的库,开发人员就会很高兴。 尝试在使用不同库的域之间进行通信时会出现痛苦。 突然出现了一个问题,因为不同的库支持不同风格的 JSON。

我们是否应该通过使 JSON 库尽可能宽松(但最终可能会变得复杂和模棱两可)或攻击根本原因来消除痛点? 非确认 JSON 库。

由于有影响力的 MS 可能有很多要求 MS 成功支持符合标准的 JSON 解析器,以便从长远来看提高互操作性,但我希望它有所不同。 或许读宽,写严?

(不在标准中的东西;注释、尾随逗号、单引号字符串、无引号字符串等)

恕我直言,由于 JSON 起源于网络浏览器世界,似乎为了互操作性,我们应该选择 double 作为 JSON 中数字的底层表示,即使 JSON 标准没有说明代表。

说到 API,我隐含地假设最常用的 API 将是类似于 API 的 DOM,但如果有一个较低级别的 API 允许我使用令牌流或在访问者界面上获得信号,我也会发现它非常有用那些我只想从中提取一小部分数据的大型文档。

@mrange - 尽管我喜欢使事情尽可能严格......这样做依赖于对不符合规范的代码进行更改的能力。

如果您正在与受其他公司控制的遗留服务进行交互,则更改违规代码的能力几乎为零。 即使是严格写入,虽然更可行,但这里也有它自己的问题:如果违规代码希望将不符合标准的对象发送给它怎么办?

@terrajobst谢谢! Func<Stream, CancellationToken, Task<T>>Func<T, CancellationToken, Stream, Task>就是这里所需要的。 可能有一些 TextReader/Writer、Span 和 string 的重载。

然而,缺点是当您想要序列化/反序列化另一个库的类型时,该类型使用来自您未使用的 json 序列化程序的属性进行修饰。

@thefringeninja如果您已经在为对象使用第三方库,那么您已经拥有对其他序列化程序的引用。 那里什么都没有改变。

我不是一个害怕散布的人,但我确实认为@mythz有一些有效的观点。

@terrajobst关于生态系统,虽然不可能考虑到那里的每个库,但我认为在 NuGet 上快速搜索“json”不会告诉任何人太多。 也许 ServiceStack.Text 这个名字并不是说“嘿!我是一个可以(反)序列化 JSON 的包!”的最直接的方式,但多年来一直有基准比较它。 也许这是一个对 MS 默认设置进行测试的案例,或者不知道替代方案的广度和受欢迎程度,或者在内部频繁使用它们以熟悉它们。

我同意应该有一些默认设置来提供一种 _just 有效_ 开箱即用的体验。 如果生态系统中的其他库作者发布了一个集成包,如果他们能在文档、发行说明等中插入插件以强调除了默认值之外还有其他选择,那就太好了。 很难发现对生态系统来说是个问题。

我的希望是,如果删除依赖的目标是真诚的,API 应该最好地代表社区的需求,而不是直接模仿 Json.NET。 最重要的是,它需要所有库作者的工作,而不仅仅是 ServiceStack,但 API 不应直接类似于 Json.NET 的 API,否则您将回到看起来像依赖项但没有 dll 的情况。

API 不应直接类似于 Json.NET 的 API

...或任何其他特定提供者的实现。

在宣布之前发生的部分讨论包括这样一个想法,即 .Net 团队将从各种库中汲取灵感,以了解各种问题是如何解决的,然后使用他们认为最适合这些库的方法结合自己的想法。 在许多方面,它与任何其他新 JSON 库的开发方式没有什么不同; 碰巧这一点将包含在框架中。

我们全力以赴拥有一个不必自己构建的高性能 JSON 库。 :)

在讨论任何事情之前,请考虑利用 Microsoft Research 在该领域的结果(更具体地说,无分支无 FSM 解析) https://www.microsoft.com/en-us/research/publication/mison-fast-json-parser -数据分析/

我们正朝着高性能 JSON 解析的方向前进 --- 当然除了Span<T> ---
抄送@terrajobst @karelz

:( 所有关于 JSON 的讨论让我觉得我关于模板的问题出了问题。

我希望我有更多的时间进行这次讨论,因为它一直是地狱,但我明白为什么它会变成现在这样。 4.6.1 必须与升级和升级保持一致,其余的将是重大更改。

我已经看到很多关于 core 和 461 的召回包,我希望这种类型或更改能够解决它。

我担心级联问题会困扰我们,请证明我们错了。

// dot net devs无处不在

@c0shea

[...] 如果他们能在文档、发行说明等中插入一个插件来强调除了默认值之外还有其他选择,那就太好了。

我相信情况会如此。 这些文档已经列出了多个主题的替代实现,例如DI 容器日志记录提供程序Swagger 集成EF Core 数据库提供程序

@菲利普海顿
模板系统已经支持可定制的模板,现有的模板其实已经有很多选择了。 只需查看例如dotnet new mvc --help以了解当前可能的情况。 我相信你可以很容易地扩展它,例如替代 JSON 序列化器集成,并且可能会在aspnet/Templates接受功能请求或拉取请求。

@mrange - 尽管我喜欢使事情尽可能严格......这样做依赖于对不符合规范的代码进行更改的能力。

如果您正在与受其他公司控制的遗留服务进行交互,则更改违规代码的能力几乎为零。 即使是严格写入,虽然更可行,但这里也有它自己的问题:如果违规代码希望将不符合标准的对象发送给它怎么办?

也许默认情况下有一个严格模式,并且能够明确地将其切换到更宽松的模式

@poke我想你真的需要去尝试 vue cli,然后重试 dotnew new。 当前的 dotnet 新...是...它是...

我能否请您记住,各种浏览器对 JSON 的解析不正确支持 int64 值,并让我们能够将 long 序列化/反序列化为字符串? 这是你不会注意到的事情之一,直到它狠狠地咬你。 对此的一个变体是能够决定默认情况下数字是反序列化为整数还是长整数。

我能否请您记住,各种浏览器对 JSON 的解析不正确支持 int64 值,并让我们能够将 long 序列化/反序列化为字符串? 这是你不会注意到的事情之一,直到它狠狠地咬你。 对此的一个变体是能够决定默认情况下数字是反序列化为整数还是长整数。

....啊,EcmaScript,感谢你让一切都翻倍了。 我确定这不会在代码的其他部分引起问题......

作为一个纯粹主义者,我不喜欢这样的东西。
作为一个现实主义者,我想我将不得不同意这一点。

新 JSON 实现的任何部分都在.Net Standard 2.1 中吗?

我一直在关注这个,我不确定我是否错过了它。 是否有我可以审查的提议的 API 表面或接口? 我有兴趣查看此提案的 API 表面积。

是否有我可以审查的提议的 API 表面或接口?

还有很多事情要做,但https://github.com/dotnet/corefx/pull/33216只是一个开始。 这是API 审查说明

更新:路线图也可在此处获得

那么,aspnet 3.0 api 与 json.net api 相比,功能有多完整? 此外,用于所有意图和目的的 json.net 是否会通过开发具有本机 api 的新应用程序而被淘汰?

只是提高性能还是意味着替换json.net的所有功能?

这是一个惊人的消息。

我强烈建议尝试与@neuecc合作,他在MessagePackUtf8JsonZeroFormatter等方面的工作非常出色

@linkanyway结果将是替换 json.net 的一个子集,同时提供新的无分配 api。

我怀疑大多数 aspnet 用户不会对 json.net 实现有很强的依赖性,并且能够几乎无缝地迁移。

是否有我可以审查的提议的 API 表面或接口?

还有很多事情要做,但 dotnet/corefx#33216 只是一个开始。 这是API 审查说明

更新:路线图也可在此处获得

@khellang我们是否会获得任何可以在 c# 中真正编写 json 的 lang 帮助?

OSS方向的又一个好动作。 将激励其他商业平台的开发人员免费开发比 MS 已经做的更好的东西,或者如果他们真的关心社区,就成为完全的 OSS。

我们是否会获得任何可以在 c# 中真正编写 json 的 lang 帮助?

@dotnetchris我不确定“lang help”是什么意思? JSON 文字? 我怀疑这会发生。 您是否看过即将推出的“嵌入式语言”功能? 专门用于 JSON

@khellang这当然是朝着正确方向迈出的一步,但我的意思是全力支持。 使用链接中的相同示例对象,更类似于:

json v1 = { 
                    first: 0, 
                    second: ["s1", "s2" ] 
                }

var andCsharp = v1.second.Where(item => item.EndsWith("1"));

有了足够多的伏都教,例如隐式元组/值元组/记录对象生成,使所有这些都在幕后的 lang 级别工作。

相反,编译器可以调用 json 服务,创建一个类,然后使用该类的实例,就像您编写的一样:

var v1 = "{ first: 0, second: ['s1', 's2' ] }".Deserialize<MyV1>();

编辑:哈哈@downvoters。

@dotnetchris如果您有兴趣,请在https://github.com/dotnet/roslyn/pull/24110 上投票

“内置”和“平台提供”JSON API 是否意味着它不会是一个单独的(网络标准)nuget 包? 如果不会,为什么不呢?

我想新的 ASP.NET Core 共享框架不能依赖于 nuget 包,或者可以吗?

不是已经有System.Json命名空间了吗? 这是将要为 .NET Core 3.0 和最终 .NET Standard 使用/扩展的命名空间吗? 该命名空间已在 Xamarin.Android 7.1+、Xamarin.iOS 10.8+ 和 Xamarin.Mac 3.0+ 上使用(可能使用不多,但可用 😅)。

删除它会破坏向后兼容性。 离开它并开始一个新的 API 可能会引起一些混乱。 在添加新 API 时,在不删除任何 API 的情况下扩展/增强它可能会受到一些限制。

拥有 JsonReader/JsonWriter 的接口会很棒,因为除了流之外还有其他源和目标。 例如,我也将 JSON.NET 用于 MongoDB。 它更快,我不必在我的应用程序中维护多个序列化程序。

我知道它可能会稍微影响性能,但它非常有用。

@SebastianStehle :JsonReader/JsonWriter 是高级抽象,请参阅 terrajobst 的评论

3.0的计划如下:

  1. 内置高性能 JSON API。 低级读取器/写入器、基于流的读取器/写入器和 > 序列化器。
  2. ASP.NET Core 可插入 JSON 组件。

有一个开放式问题,即 3.0 中的 ASP.NET 模板将使用什么。 根据我们在 3.0 中可以提供的保真度,我们可能会让它们包含在 Json.NET 集成包中。 然而,我们的目标是提供足够的保真度和奇偶校验,默认情况下仅依赖于内置的。

高级、易于使用的 API 将被包裹在流周围,以便轻松地从流中反序列化(这通常是最常见的,在序列化时。如果您想在无法使用流的情况下获得最佳性能,则应该使用低在Span<T>Memory<T>上运行的级别 API,尤其是当您手头/内存中已有数据时,您想使用这些数据并且没有异步开销。

@TsengSR

由于性能原因(我猜是虚拟调用和分配), https://github.com/neuecc/Utf8Json不提供编写自定义读取器/写入器的功能,我认为他们希望走相同的道路。 但到目前为止我还没有看到任何序列化代码。

我同意@JonasZ95@gregsdennis ,我希望实现不会是相同 JSON.Net 实现细节的简单抽象,而是专注于它_应该_是什么样子。

我也认为它应该作为 2 个独立的功能来处理......

  1. 序列化/反序列化
  2. 所述序列化和反序列化的 json 版本。

希望 ASP.NET Core 框架将使用通用序列化抽象而不是 JSON 特定抽象。

至于可扩展性,我希望框架将使用 DI 编码技术进行抽象(接口而不是抽象类)并简单地提供本地默认值。 从 JSON 库作者的角度来看,这将提供最大的可扩展性,因为您只需提供一个 ASP.NET Core 适配器类,该类使用接口的库实现,然后配置 ASP.NET Core 以使用库适配器。

3rd 方库的实现可能如下所示:
```C#
// 引用第 3 方库
使用 Newtonsoft.Json;

// 为简洁起见的非常幼稚的例子
// 提出要点
公共类 NewtonsoftAdapter : ISerializer
{
私有 JsonSerializerSettings _settings;
私人格式化_format;

public NewtonsoftAdapter(JsonSerializerSettings Configuration, Formatting FormatOption)
{
    _settings = Configuration;
    _format = FormatOption;
}

    // interface method
public string Serialize<T>(T Subject)
{
    return JsonConvert.SerializeObject(Subject, _format, _settings);
}

    // interface method
public T Deserialize<T>(string SerializedContent)
{
    return JsonConvert.DeserializeObject<T>(SerializedContent, _settings);
}

}

...

// 使用第 3 方自定义选项设置适配器
var 设置 = 新的 JsonSerializerSettings
{
MissingMemberHandling = Newtonsoft.Json.MissingMemberHandling.Ignore
};
var adapter = new NewtonsoftAdapter(settings, Formatting.Indented);

//配置asp.net核心
// 适配器实现 ISerializer (或任何你想出的名字)
// 库作者甚至可以提供他们自己的 UseXYZ() 扩展方法。
app.UseSerializer(适配器);
``

基于 SIMD 的文本解析有很多进步,包括结构化文本,如JSON 。 .NET Core 中的工作有可能达到这个性能水平吗? 有什么方法可以使用这些技术吗?

嘿,即使是微软研究院也有一些新的高性能解决方案

@AnthonyMastrean感谢您提出这个问题。 我也对任何基准测试感兴趣,以了解当前的 Json impl 与 simdjson 的比较。

顺便一句,simdjson 的作者在 HN 上阅读有趣讨论

有什么方法可以使用这些技术吗?

.NET Core 3.0 恰好提供了一堆平台相关的内在函数,所以它绝对是可行的 😄

就其价值而言,我认为在 Web 范围内,网络是主要瓶颈,虽然您可以在几秒钟内解析千兆字节很酷,但我认为这对 Web 项目不是很有用。

不要误会我的意思,像这样的性能优化非常酷,甚至可能会使非常小的 JSON 文档受益。 但就目前而言,我认为新库的重点是避免内存分配并将所有内容都非常靠近网络层。 仅这一点就应该已经大大提高了 JSON.NET 的性能。 但是当初始工作完成后,寻找额外的优化可能是另一回事。

在我工作的地方,我们每天解析 TB 字节的 JSON。 我也知道其他人也使用 .NET 和 F# 来处理大量 JSON 文档。 JSON 已不仅仅是服务器 => 浏览器传输机制。 它在纯后端场景中被大量使用。

离岸金融中心; 后端切换到像 AVRO/Protobuf 这样的二进制格式会更好,但通常这很困难,而且 JSON 确实有一些好处(我勉强承认)。 拥有一个真正快速的 JSON 解析器可以为与我们类似的公司每月节省 10,000 美元。

@poke该项目属于 .NET Core(而不是 ASP.NET...),因此它与所有工作负载相关,而不仅仅是 Web。

我同意为 .NET Core 3.0 进行这种特定优化技术为时已晚的想法,但我希望现在进行一些调查以确保将来可以进行优化(即不会破坏更改)。

可能更好地制作诸如统一映射程序集('System.Text.Json.Mapping')之类的东西,其中定义用于将 JSON 映射到 C# 类的属性和其他东西? 实现这个东西后,所有现有的 JSON Parsers/Writers 都可以采用统一映射。 它将使所有 .NET Standard 应用程序能够在不同的 JSON 库之间轻松迁移

@AlexeiScherbakov新的抽象实际上并没有多大帮助。 您将通过选择一个通用抽象再次限制自己,并且总会有新的库无法使用该抽象并需要更多。 一直都是这样,例如使用 logging

我不认为基于这个新实现创建一个新的抽象会给我们带来任何好处,尤其是当库被设计成功能不那么丰富的时候。

并且实际上已经存在以 DataContract/DataMember 形式存在的网络标准抽象,我希望这个库最终会得到尊重(即使该抽象有些有限)。

除了忽略属性之外,我们不能有十亿个新属性和场景来满足。 宁愿将 JSON 1:1 映射到类,如果您想做任何超出规范的事情或支持遗留,请使用 json.net。

我个人不太关心 JSON <=> C# 类。 我认为将解析/编写 JSON 的概念与创建的 C# 对象模型和 JSON 模型分开是很重要的。
这样我(不太关心 JSON <=> C# 类)可以拥有一个真正高效的解析器,而无需在某种对象模型上进行往返。

@mrange这就是读者和作者的用途

这是否意味着我可以在平台提供的 JSON API 中使用 Reader/Writer API? Reader/Writer 模式是最有效的模式吗?

目前System.Text.Json

  • Utf8JsonReader - 一种读取 UTF-8 编码的 JSON 文本的快速、非缓存、只进的方式。
  • Utf8JsonWriter - ^ 与Utf8JsonReader ,但用于写作。
  • JsonDocument - JSON 有效负载的只读随机访问文档模型。

以上所有类型都应该(或多或少)免费分配👍

我们发布了 simdjson 论文: https ://arxiv.org/abs/1902.08318

simdjson 的 C# 端口也正在进行中: https :

抄送@EgorBo

可能更好地制作诸如统一映射程序集('System.Text.Json.Mapping')之类的东西,其中定义用于将 JSON 映射到 C# 类的属性和其他东西? 实现这个东西后,所有现有的 JSON Parsers/Writers 都可以采用统一映射。 它将使所有 .NET Standard 应用程序能够在不同的 JSON 库之间轻松迁移

我真的希望新的抽象不依赖于属性。 我尝试在底层库中使用干净的 POCO 对象并使用 DI 来避免他们必须了解实现。 我绝对不想用实现所需的属性来装饰我的底层类。 这可能最终导致在 ui 层中创建额外的类,这些类基本上只是将现有域对象映射到 json。

json 到 c# 类的 1-1 映射可能是一种更好的方法,至少在某些情况下,即使在其他情况下仍然需要 viewmodel 类型类,您也可以避免创建新类。

如果有某种方法可以忽略不需要的属性并至少控制一些序列化方面(例如骆驼与帕斯卡大小写),那将会很好。

@mrange这就是读者和作者的用途

@davidfowl 这是否意味着新的 API 正在走这条路? 设计已经完成了吗?

正如我们所说,序列化支持正在登陆。 相关问题说:

  • 由于时间限制,并且为了收集反馈,该功能集旨在为 3.0 提供最小可行的产品。
  • 目标是简单的 POCO 对象场景。 这些通常用于 DTO 场景。
  • 该 API 旨在针对后续版本和社区中的新功能进行扩展。
  • 用于定义各种选项的设计时属性,但仍支持在运行时进行修改。
  • 使用 IL Emit 实现高性能,并回退到兼容的标准反射。

它还详细说明了他们计划如何支持枚举转换、空处理、camel- vs PascalCasing 等。

如果您对此有任何反馈,您应该在该问题或拉取请求中留下您的评论。

@lemire哇,这真的很酷。 simdjson 确实超级快。

您是否有机会实现TechEmpower

我找到了这些实现:在 TechEmpower 存储库ASP.NET 存储库中

@KPixel这是序列化,对吧? 同时 simdjson 是一个解析器......除非我对这些术语感到困惑,否则这些东西会走向相反的方向?

我的错。 我假设有一个反序列化部分(将使用解析器)。

System.Text.Json是 .net 标准的 nuget 包吗? 还是仅适用于 .net core 3.0 的东西?

@John0King看看这里: https :

我认为可用性也应该是新 JSON 包的重点。 我认为它应该具有的一项功能是 JSON 模式验证支持。 Newtonsoft 为此收费。 这是一个足够基本的东西,它应该在平台中免费提供,就像 XML 模式验证的情况一样。

@jemiller0我的印象是 XML 验证在某种程度上是一个混合包,而 JSON 模式在现实世界中的采用情况一般。 作为一个额外的步骤,您始终可以通过库进行模式检查……当然,这可能涉及获取软件许可证,但这有什么大不了的吗?

@lemire是的,如果您正在开发开源软件并希望将您的软件提供给所有人,这很重要。 XML 解析不是一个混合包。 有用。 与 JSON 模式验证相同。 没有内置的免费方式来做到这一点使得 .NET 平台没有竞争力。

我从未见过在现实世界中使用过 json 模式。 即便如此,它应该在这里讨论的实现的一部分。 json.net 中的十亿其他特性和怪癖都不应该在这里实现。 这应该无非是超轻量级快速实现。 如果您不满意您需要 json.net 的许可证来支持 json 验证。 创建您自己的开源实现并使其免费可用。

@杰米勒0

我真的很好奇:其他编程语言是否在其标准库中提供 JSON 模式支持?

这个库的目标是成为一个高性能的低级库来处理 JSON。 任何不是这样的东西,包括来自 JSON.NET 的大多数更高级的功能以及 JSON 模式,都不会成为其中的一部分。

如果您想要 JSON 模式验证,您可以自由地在这个库之上实现一个验证器,它应该足够低级以允许您这样做。

我不认为在标准库中进行 JSON 模式验证与平台是否具有竞争力有任何关系。

这个库的目标是成为一个高性能的低级库来处理 JSON。 任何不是这样的东西,包括来自 JSON.NET 的大多数更高级的功能,都不​​会成为其中的一部分。

除了它还将包括更高级别的功能,旨在替代 Newtonsoft.Json 😊

@poke你有权拥有你想要的任何意见,就像我一样。 XML 无处不在。 因此,Microsoft 正确地将验证支持包含在 .NET Framework 中。 现在,JSON 风靡一时,在配置文件、Web API 等中无处不在。对 JSON 的支持级别与 XML 的历史支持级别相同是有意义的。 就我个人而言,我觉得微软开始使用第三方软件有点荒谬。 这应该是该平台的核心功能。

@lemire我很快就会检查 Python。 在这一点上,我会发现它是内置的,或者作为一个易于安装的包包含在内。 如果不是,我会非常惊讶。 我正在考虑使用 NJsonSchema 来满足我现在的需要。 在顶部,您可以看到文档很烂。 是的,对于使用 JSON 之类的东西来说,依赖质量可能高也可能差的第三方库是一个好主意,因为 JSON 无处不在,而且无处不在。 让我们都依赖于商业软件或没有文档的第三方软件包。 .NET 不应该只匹配 Python 等其他平台。 他们应该通过提供带有开箱即用适当文档的高质量软件来击败他们。 从历史上看,这就是它的运作方式。 在我工作的地方,每个人都讨厌 .NET 并想强迫我使用 Python。 不知道你有没有注意到,但是,越来越多的人正在弃船转向 Python。 告诉我的老板我需要购买许可证才能做一些简单的事情,比如验证 JSON 不会成功。 我将得到的回报被质疑为什么我首先要使用 .NET。 没关系,这是一个开源项目,无论如何你都无法获得许可证。 希望我会发现 NJsonSchema 可以正常工作。 我只是指出框架中的一个明显遗漏,对于任何使用 JSON 的人来说都应该是显而易见的。

我在工作中使用 JSON 模式,我宁愿拥有一个真正好的 JSON 解析器,而不是一个半好的 JSON 解析器 + JSON 模式验证器。 此外,AFAIK JSON Schema 现在是 _draft_ 7。 因此,将 JSON 模式作为可以与模式一起快速发展的外部库对我来说很有意义。 不过在路线图中有 JSON Schema 会很好。

@杰米勒0

对 JSON 的支持级别与过去对 XML 的支持级别相同是有意义的。

.Net 还包括对 XSLT 和 XPath 的支持。 如果您想要“相同级别的支持”,这是否意味着您还需要某些版本的 JSON 支持?

我想说的是:JSON 生态系统不同于 XML 生态系统。 两者都有不同的使用模式,相关技术的使用数量和标准化程度也不同。 此外,在 NuGet、git 或 GitHub 出现之前,XML 就被添加到 .Net 中。 如今,依靠 3rd 方库更容易也更容易接受。

所以,不,我认为盲目地说“XML 有这个,所以 JSON 也必须有”是没有意义的。

此外,验证与解析完全正交。 我绝对可以在某个时候添加验证支持(可能完全在另一个包中)。 但是对于正确的解析支持,它根本不是必需的。

我们需要一种方法来严格验证 API REST 请求中的数据。
因为我们保存了通过 API 来的 json 没有错误,后来我们因为尾随逗号等原因无法在 JS 中解析它。

为什么您现在不能验证该请求?

@phillip-haydon @ freerider7777 我认为任何合适的 JSON 解析器都应该遵守 JSON 规范,并在文档格式不正确时(例如,当它有尾随逗号时)抛出错误(和/或警告)。 这是非常基本的,但也不同于验证

https://tools.ietf.org/html/rfc7159

微软是最大的软件开发公司之一,没有任何人从事验证工作。 一个快速的解析器更重要。 它将让您以光速解析无效的 JSON。 :-) 任何人都没有想到快速验证可能有用。 这就像 ASP.NET Core,对 Web 窗体的快速简化升级。

为什么您现在不能验证该请求?
@phillip-haydon 在带有这样 json 的控制器代码中:
ModelState.IsValid == true

🤦‍♂️

您可以使用NSwag + System.ComponentModel.DataAnnotations根据您的 json 模式进行验证:

<Project Sdk="Microsoft.NET.Sdk" >
  <ItemGroup>
    <PackageReference Include="NSwag.MsBuild" Version="12.0.10" />
  </ItemGroup>
  <ItemGroup>
    <Compile Remove="**\*.g.cs" />
  </ItemGroup>
  <ItemGroup>
    <SchemaFiles Include="$(MSBuildProjectDirectory)\..\schema\*.json" InProject="false" />
    <EmbeddedResource Include="$(MSBuildProjectDirectory)\..\schema\*.json" LinkBase="Messages\Schema" />
  </ItemGroup>
  <Target Name="GenerateMessageContracts" BeforeTargets="GenerateAssemblyInfo">
    <Exec Command="$(NSwagExe_Core21) jsonschema2csclient /name:%(SchemaFiles.Filename) /namespace:MyNamespace.Messages /input:%(SchemaFiles.FullPath) /output:$(MSBuildProjectDirectory)/Messages/%(SchemaFiles.Filename).g.cs" />
    <ItemGroup>
      <Compile Include="**\*.g.cs" />
    </ItemGroup>
  </Target>
</Project>

我同意@lemire ,验证 JSON 的结构和根据模式验证 JSON 是有区别的。 我毫不怀疑微软已经花费了时间和精力来正确实现前者……后者是一个极端情况,我认为它不适合这个 JSON 库的总体设计。 我很确定他们已经明确表示,这个 JSON 库旨在提供快速、高效、解析 asp.net 核心运行所需的功能。 它的设计目的不是包含 newtonsoft 解析器附带的 _extras_。 (请参阅线程前面@poke的评论)。

我不认为他们故意没有设计这个带有所有花里胡哨的东西的事实使它成为劣质产品。

这是否发生在预览版 4 中?

是否有计划制作 System.Text.Json.Serialization.Policies.JsonValueConverterclass public 是否允许从 Json.net 替换转换器类?

System.Text.Json通过 nuget 提供完整的 .Net 支持? 确保完全互操作并利用完整框架的好处肯定会很好。

System.Text.Json最近更改为生成netstandard2.0二进制文件以用于运送 OOB; https://github.com/dotnet/corefx/pull/37129

如果可能,您应该面向 .NET Core 3.0 并获取内置 System.Text.Json API。 但是,如果您需要支持 netstandard2.0(例如,如果您是库开发人员),则可以使用我们的与 netstandard2.0 兼容的 NuGet 包。

受益于完整的框架

这些又是什么? 🤔

@赫朗

我的偏好是具有多种风格的 nuget,包括完整框架(4.5 或任何可接受的最低限度)、标准和核心。 最好使用盒装组件。

上面链接的问题是指这个包,但它不受支持:

https://www.nuget.org/packages/System.Text.Json

是否有当前支持的软件包?

我的偏好是具有多种风格的 nuget,包括完整框架(4.5 或任何可接受的最低限度)、标准和核心。

你为什么更喜欢那个? 如果不需要多目标,即所有使用的 API 都是标准的一部分,那么只有一个目标会更好😊

是否有当前支持的软件包?

我认为它还没有发货。 PR 几天前合并了。 该软件包曾经是一个社区项目,现在已转移到 MS。

@khellang这取决于具体情况——我是在做一般性声明。

如果网络标准版本必须从网络核心版本中省略网络完整版本可能的任何内容,我希望所有三种版本都可用。 我怀疑,与上面链接问题中关于更喜欢用户针对内置版本的原始声明相同的一般推理。

添加对 nuget 包的引用时,将自动选择最合适的风格。 所以,这没什么大不了的。 如果消费库是净标准,则将选择净标准风味。

我对盒装风格的一般偏好是,当我goto definition ,我会得到反编译的源代码。 如果我在网络标准库上使用goto definition ,我通常只会看到抛出NotImplemented异常的存根源。

受益于完整的框架

这些又是什么? 🤔

许多应用程序使用 .NET Framework 并不是因为他们绝对不想使用 .NET Core,而是因为 .NET Core 不是一种选择。 我选择使用 .NET Core; 当我必须针对低于 Windows Server 2012(最低 .NET Core 3.0 版本)的 Windows 版本时,我必须使用 .NET Framework。 正如我确信放弃对 Windows Server 2008 R2 及更低版本的支持是一个非常痛苦的决定,对于每家拥有付费客户的公司来说,这是一个非常痛苦的决定,他们的服务器不想升级/通常基本上是从头开始重新创建只是为了我们可以使用稍微更新的工具。

如果我明天就可以停止使用 .NET Framework,那么没有人会比我更高兴,但即使有 .NET Core 3.0 及更高版本中的所有 WPF 和 Windows Forms 机会,Microsoft 正在通过其支持策略使这成为实际不可能的事情。 我曾试图与任何愿意在 Microsoft 听取意见的人讨论这个问题,但遗憾的是,我还没有收到一封确认消息已送达的电子邮件。

@JesperTreetop更不用说缺少对值得为企业使用的 .NET Core 版本的 LTS 支持;) 我希望我们能在 3.x 上获得 LTS 支持——作为我组织的 .NET 架构师,我将推动如果我们获得支持 LTS 的 3.x 版本,则采用 .NET Core。

@marksmeltzer 昨天的博客文章Introducing .NET 5显示 .Net Core 3.1 将成为 LTS,并计​​划于 2019 年 11 月发布。

这个新的 JSON 序列化程序是否支持 F# 类型?

@rliman目前它不支持 Guid 或 Enum,所以它还有很长的路要走。 我同意完全支持 F# 选项类型类似于 C# 可为空的,恕我直言

我个人认为这是对糟糕的架构设计决策的匆忙解决方案。 这应该早就完成了......现在它会在任何地方引起很多痛苦......从库开发人员到企业开发人员。

没有简单的方法来“平滑”这个新的“功能”。

这是 MS 试图解决他们首先引起的问题。 而现在每个人都必须付出代价。

NET Core 似乎从一开始就有点“快速”......这种纯粹的“敏捷”方法可能需要放慢一点,让每个人都喘口气。

似乎在 ASP.NET Core 中,这些“功能”(重大更改)已成为新常态。

在我看来,ASP.NET Core 迫切需要重新设计他们的架构设计过程。 因为一次又一次地制作这些“我们稍后会修复它”的功能。

自从 ASP.NET Core 处于早期测试版以来,我一直在使用它进行开发……这是对 .NET 的巨大改进。

但是 MS 团队应该停下来思考一下他们​​如何解决这里的真正问题:仓促和不一致的架构设计决策。

只需返回并阅读其他线程......似乎这是一个反复出现的主题。

因此,也许是时候坐下来重新思考制作更稳定产品的最佳方法了。

经典的 .NET 可能不如 Core 强大……但它自 2.0 以来就非常稳定和一致。

只是我的观点。

@suncodefactory
我记得前段时间,当 ppl 因不使用开源库而对 ms 大喊大叫时,现在他们因这样做而受到指责:D
从我的角度来看,Aspnet/core MVC api 自 mvc1/2 以来一直非常稳定! aspnet 从 2.0 开始稳定的原因是它根本没有改变/改进😄。
老实说,如果您正在使用序列化库的高级功能,您有机会重新考虑它,并可能使用适合该任务的数据结构来解决问题,而不是假装所有序列化程序都支持所有语言功能,imo要解决的错误问题,以及使用序列化的错误方法。
清晰性、向后兼容性和未来扩展是驱动我的可序列化 dtos 的驱动力,在通用业务逻辑对象中使用的非常不同的权衡(那些是私有的,有很多功能等。)

我们能够将微服务从网络框架迁移到 Linux(网络核心),而几乎不需要产品团队的任何努力。 我不知道你们在说什么。 微软在加速实施这些早就应该发生的变化方面做得很好。

@suncodefactory
我记得前段时间,当 ppl 因不使用开源库而对 ms 大喊大叫时,现在他们因这样做而受到指责:D

对我来说,重点不在于第三方库……而在于在这种特殊情况下缺乏或完全错误的架构设计。

此外,我从未谈论过经典的 asp.net...我谈论的是 .NET Framework 2.0。 它稳定的原因不是因为没有你错误声称的改进(因为 .net 核心基于 .NET 4.6.1)。 原因是因为它的规划和架构都很好。

至于aspnet核心与经典的asp.net mvc相比有多好,这与这个特定线程无关。

该线程是关于 MS 将在没有彻底考虑的情况下再次发布的重大更改。

我们能够将微服务从网络框架迁移到 Linux(网络核心),而几乎不需要产品团队的任何努力。 我不知道你们在说什么。 微软在加速实施这些早就应该发生的变化方面做得很好。

像这样的变化根本不应该发生......所以你对破坏性变化感到满意吗?

并且说 asp.net 核心团队在交付变化方面做得很好,这完全是不正确的。

从 beta 3 开始,我一直在使用 asp.net core 进行开发,我很确定缺少架构设计过程。

至于asp.net核心与经典相比有多好......我不反对,因为我也相信比经典更好。

但是仅仅因为asp.net core 比classic 好并不意味着他们在架构设计方面做得很好。 这两个是完全不同的话题。

我们能否将此讨论限制在 .NET Core 3 中的 JSON 功能上?

像这样的变化根本不应该发生......所以你对破坏性变化感到满意吗?

所以不应该做任何改进吗? 如果您不想让软件进化、成长和变得更好,为什么还要成为程序员?

@suncodefactory

像这样的变化根本不应该发生......所以你对破坏性变化感到满意吗?

啊,拜托,你说“破坏性更改”意味着你必须放弃你的项目并从头开始。

您可以计算 ASP.NET Core 2.x/3.0 中有多少重大更改需要超过

  • 引用不同的包
  • 使用不同的命名空间
  • 更改超过 5 行代码
  • 删除 1-2 行代码(即选项类中的属性)

??

@suncodefactory

该线程是关于 MS 将在没有彻底考虑的情况下再次发布的重大更改。

这实际上是一个_破坏_变化? 新的 JSON API 是 .NET Core 中引入的一组全新的 API,它们既不会删除也不会破坏任何现有内容。 是的,您最终会看到事物和库转向它,因为它提供了不同的优化机会,但您不会被迫将其应用到您的代码中。

特别是谈到 ASP.NET Core,尽管 _“这与这个特定线程无关”_,如果你依赖 Newtonsoft.Json 的一些更高级的功能,你可以选择继续使用它。 是的,您必须为此更改一些代码才能使其工作,但我认为这并没有真正破坏,因为如果您真的想升级到新版本,您只需要这样做。 这就是现在的好事:你有更多的选择。

如果您出于某种原因不喜欢此功能,请随时坚持使用已知、稳定且固定的功能集的 .NET Framework。 这将在那里停留很长一段时间,所以你可以完全依赖它。 但是,当_“这与该特定线程无关”_时,请停止使用该线程来传播您的反新事物议程。

来自 EF Core 用户的两个问题。

  1. System.Text.Json支持循环引用? 循环引用可能出现在 EF Core 数据中,其中在类之间存在双向导航链接。 Json.NET 使用类似的设置来处理这个
    c# var json = JsonConvert.SerializeObject(entities, new JsonSerializerSettings() { PreserveReferencesHandling = PreserveReferencesHandling.Objects, ReferenceLoopHandling = ReferenceLoopHandling.Ignore });
  2. 随着带有私有 setter 和私有构造函数的 DDD 样式类的兴起, System.Text.Json反序列化这些类型的类吗?

@JonPSmith IMO 应该没关系。 您永远不应该直接序列化实体。 您应该序列化一个投影。 这避免了循环引用,并且不会公开所有数据,尤其是当您向可能最终变得敏感的实体添加更多属性时。

@JonPSmith :恕我直言,从最佳实践和 DDD 的角度来看,这两个用例都是无效的。

  1. 我从未见过推荐直接反序列化实体的最佳实践(最简单的教程示例除外)。 循环引用总是有代价的。 它需要跟踪已处理的对象,这意味着:内存分配和额外的 CPU 周期。 但是新 JSON 库的邮件目标之一是完全避免这些内存分配
  2. 也无效,因为您从未序列化为域模型,尤其是当您通过 Web 请求(例如 WebApi 调用)获取数据时。 在 DDD 中,您应该始终使用事件/命令,将命令发送到您的 Web 应用程序,从存储库中获取(并脱水)实体(通过 ORM 映射或 EventSourcing),应用命令,将其持久化。

最重要的是,新的 JSON API 适用于高性能场景。 对于需要丰富功能集的其他所有内容,您(并且应该)仍然使用 JSON.NET 或满足您需求的任何内容。

@suncodefactory这与重大更改相反。 目前,在 ASP.NET Core 2.2 中,框架和用户代码都使用 JSON.NET。 这有可能与您自己使用 Newtonsoft.Json 产生冲突; 如果 ASP.NET Core 3.0 转移到 JSON.NET 12.x 并且那里有某种问题破坏了您的应用程序,那么您就会遇到问题。

例如,查看Microsoft.Extensions.Configuration.Json 2.2.0 - 它依赖于 Newtonsoft.Json 11.0.2。 那是一个配置包; 与 HTTP 请求处理或 ASP.NET Core MVC 无关。 或者查看Microsoft.IdentityModel.Protocols.OpenIdConnect ,它使用它来处理 JSON Web 令牌; 这是一条需要尽可能多的性能的热门路径。 从任何标准来看,JSON.NET 都不是一个缓慢的库,但它在性能、功能丰富性和对大量用户场景的支持之间取得了平衡。 Microsoft 的新 JSON 库不需要这样做,因为 JSON.NET 存在。 因此,它可以专注于以最高性能处理绝对基础。

.NET 在System.Runtime.Serialization.Json 中一直有自己的 JSON 序列化解决方案,但在 .NET Core 的高性能世界中,它并不是一个很好的解决方案。 我当然不希望它被调用来检查每个传入请求的凭据。 非常欢迎具有现代 UTF-8 数据处理和最小分配的新 JSON 库。

您仍然可以在应用程序中引用 Newtonsoft.Json,并像以前一样继续将其用作请求/响应数据的反序列化/序列化管道。 从现在开始,您将能够这样做而无需担心 Core 框架依赖于哪个版本。 这对每个人来说都是一场胜利。

感谢 @phillip-haydon 和@TsengSR的想法。 我在问是否会支持这些功能,你说不支持,理解和接受。 对于需要序列化/反序列化 EF Core 类的情况,我将继续使用 Json.NET。

顺便提一句。 我确实有充分的理由来序列化/反序列化 DDD 样式的 EF Core 实体类。 我有一个库,其中包含一个我称之为来自生产的种子的功能

我需要为我的客户提供这个功能,而不是只为他们编写,我将它构建到我的开源库EfCore.TestSupport 中,以便其他人可以使用它(我的客户不必为此付费)。

是否有支持[DataContract][DataMember]和朋友的计划?

今天,这是一种定义类型应该如何序列化/反序列化(例如字段名称)的方法,它不会为使用它的项目带来对任何序列化库的依赖。

当前的JsonNamingPolicy仅采用字符串,因此无法检查成员的属性。

你好。
我们只是尝试将我们的微服务切换到 DotNet 核心 3 预览版 6,但我们无法反序列化我们的不可变引用类型:具有不可变属性的类(没有设置器)并且只有一个构造函数来设置所有属性。 Json.net 正确处理这些类。
这是需要 System.Text.Json API 的问题还是支持它的计划?
感谢您的回复

谢谢@khellang。
确实计划提供支持,但不支持 3.0 版本。
似乎可以继续将 Json.net 与 DotNet core 3 一起使用,但我不知道该怎么做(添加包引用是不够的)。 有没有办法做到这一点?

@阿吉尼

C# services.AddControllers() .AddNewtonsoftJson()

谢谢你们的帮助。
有用 !
我错过了解释所有内容的迁移指南:

https://docs.microsoft.com/fr-fr/aspnet/core/migration/22-to-30?view=aspnetcore-2.2&tabs=visual-studio

IMO json.net 是半成品,使其成为破坏现有代码的默认值(即用于信号器)还为时过早。

另一方面,从 .NET Core 2.2 迁移到 3.0 是一个主要的版本升级,即使 .NET Core 团队没有严格遵循语义版本控制,我也希望在从一个版本升级到另一个版本而不进行显式更改时会出现问题(例如在管道中明确添加 Newtonsoft 的库)

鉴于这是一个公告而不是一个问题,因此关闭

虽然社区有很多反对改进的声音,但作为一个新的高性能框架,糟糕的速度是不能接受的。

我知道之前已经说过了,但我也想补充一下我的愿望。

如果我们可以拥有不可变的对象,那就太棒了。 我知道通过将Json.NET到 MVC-Pipeline 是可能的,但在我的情况下,我的测试都失败了,因为我使用的是ReadAsAsync<>现在在Microsoft.AspNet.WebApi.Client的对等依赖项中实现System.Text.Json

我们向客户提供 .NET Standard 类库,以便他们可以使用我们的库在支持 .NET Standard 的任何平台上工作。 我们需要在我们的类库中使用 System.Text.Json。 在 .NET Standard 中支持 System.Text.Json 的计划是什么?

@阿尔萨米

如果我们可以拥有不可变的对象,那就太棒了

您是否只需要能够防止其他人对其进行变异,或者您是否还需要能够创建新实例并巧妙替换部件(如不可变集合和 Roslyn)? 如果您需要前者,我们已经为您提供了即将推出的JsonDocument DOM API。

@mwoo-o

在 .NET Standard 中支持 System.Text.Json 的计划是什么?

它可用作 .NET Standard 2.0 的 NuGet 包: System.Text.Json

@terrajobst

谢谢。 此 System.Text.Json 何时会包含在 .NET Standard SDK 中?
.NET 标准 3.0(或其他一些更高版本)是否包含 System.Text.Json 包? 它会在 .NET Core 3.0 SDK 生产版本中发生吗?

@terrajobst

是否有计划使 Deserialize 方法与 PipeReader 一起使用? 或者添加可以在开始反序列化时没有所有数据的流场景中使用的 Patch 方法。

这是提议的 API 的简化版本:

private async ValueTask<T> Deserialize<T>(PipeReader reader, CancellationToken cancellationToken) 
    where T: new()
{
    T model = new T();
    while (!cancellationToken.IsCancellationRequested)
    {
        ReadResult readResult = await reader.ReadAsync(cancellationToken);
        ReadOnlySequence<byte> buffer = readResult.Buffer;

        if (readResult.IsCanceled) break;
        if (buffer.IsEmpty && readResult.IsCompleted) break;

        SequencePosition consumed = JsonSerializer.Patch(model, buffer, readResult.IsCompleted);
        reader.AdvanceTo(consumed, buffer.End);               
    }

    return model;
}

public SequencePosition Patch<T>(T model, ReadOnlySequence<byte> jsonData, bool isFinalBlock, JsonSerializerOptions options = null)
{
      ...            
}

@terrajobst

防止他人对其进行变异的能力

目前只有这个。 真的只是为了“数据传输对象”。 好消息!

@mwoo-o

谢谢。 此 System.Text.Json 何时会包含在 .NET Standard SDK 中?
.NET 标准 3.0(或其他一些更高版本)是否包含 System.Text.Json 包? 它会在 .NET Core 3.0 SDK 生产版本中发生吗?

没有 .NET Standard SDK。 .NET Standard 是一个 API 界面,可在所有支持的平台上使用。 您可以在以 .NET Standard 支持的受支持平台为目标运行的任何应用程序中提供System.Text.Json ,请参阅.NET 实现支持

@TsengSR

没有 .NET Standard SDK。 .NET Standard 是一个 API 界面,可在所有支持的平台上使用。

好吧,有一种项目类型允许您使用 API。 我认为@mwoo-o 是在问我们是否有计划将System.Text.Json到 .NET Standard。 答案是不。 是的,现在我们计划将其保留为 NuGet 包。

太可怕了,项目中应用的功能太少了。

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

sahithreddyk picture sahithreddyk  ·  3评论

noahfalk picture noahfalk  ·  3评论

omajid picture omajid  ·  3评论

bencz picture bencz  ·  3评论

btecu picture btecu  ·  3评论