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

使用System.Text.Json修改JSON文件

严兴言
2023-03-14
问题内容

我知道您可以使用Newtonsoft轻松地做到这一点。但是,当我使用.NET Core
3.0时,我正在尝试使用新方法与JSON文件进行交互,即,System.Text.Json并且我拒绝相信我要做的一切都那么困难!

我的应用程序需要列出尚未添加到我的数据库中的用户。为了获取所有用户的完整列表,该应用程序从Web
API检索JSON字符串。现在,我需要循环浏览这些用户中的每一个,并检查是否已将它们添加到我的应用程序中,然后再将新的JSON列表返回到我的视图,以便它可以向最终用户显示新的潜在用户。

由于我最终会在流程结束时返回另一个JSON,因此我特别不想打扰将其反序列化为模型。请注意,来自API的数据结构 可能会 发生变化,但是它将 始终
具有一个密钥,我可以将其与数据库记录进行比较。

我的代码当前如下所示:

using (WebClient wc = new WebClient())
{
    var rawJsonDownload = wc.DownloadString("WEB API CALL");
    var users =  JsonSerializer.Deserialize<List<UserObject>>(rawJsonDownload);

    foreach (var user in users.ToList())
    {
        //Check if User is new
        if (CHECKS)
        {
            users.Remove(user);
        }
    }

    return Json(users); 
}

这似乎是一个 很大 的篮球,以实现的东西,这将是与Newtonsoft相当琐碎通过跳跃。

有人可以建议我采取更好的方法UserObject吗?理想情况下,不需要这样做吗?


问题答案:

您的问题是您想检索,过滤和传递一些JSON,而无需为该JSON定义完整的数据模型。使用Json.NET,您可以为此使用LINQ to
JSON
。您的问题是,
这目前可以轻松解决System.Text.Json吗?

从.NET Core 3.0开始,System.Text.Json由于以下原因,此操作无法如此轻松地完成:

  1. JsonDocument,对应于JToken或的类型XDocument为只读。它只能用于 检查 JSON值,不能用于修改或创建JSON值。

当前有一个未解决的问题 Writable Json
DOM#39922对此进行了
跟踪。

  1. System.Text.Json不支持JSONPath,这在此类应用程序中通常很方便。

当前存在一个未解决的问题, 将JsonPath支持添加到JsonDocument /
JsonElement#41537,以对此进行
跟踪。

话虽如此,假设您有以下JSON:

[
  {
    "id": 1,
    "name": "name 1",
    "address": {
      "Line1": "line 1",
      "Line2": "line 2"
    },
    // More properties omitted
  }
  //, Other array entries omitted
]

以及Predicate<long>shouldSkip与您的问题id相对应的某种过滤方法,该方法指示是否应返回不包含特定条目的条目CHECKS。您有什么选择?

您可以使用JsonDocument并返回一些经过过滤的JsonElement节点集。如果过滤逻辑非常简单,并且您不需要以任何其他方式修改JSON,则这很有意义。注意,JsonDocument是一次性的,并且实际上必须需要被设置为
最小化在高的使用场景的垃圾收集器(GC)的影响 ,根据该文档。因此,为了返回a,JsonElement您必须对其进行克隆。

以下代码显示了此示例:

using var usersDocument = JsonDocument.Parse(rawJsonDownload);
var users = usersDocument.RootElement.EnumerateArray()
    .Where(e => !shouldSkip(e.GetProperty("id").GetInt64()))
    .Select(e => e.Clone())
    .ToList();

return Json(users);

样机小提琴#1 在这里。

您可以创建一个 部分
数据模型,该模型仅反序列化过滤所需的属性,而其余JSON绑定到一个[JsonExtensionDataAttribute]属性。

这应该使您无需硬编码整个数据模型即可实施必要的过滤。

为此,请定义以下模型:

public class UserObject
{
    [JsonPropertyName("id")]
    public long Id { get; set; }

    [System.Text.Json.Serialization.JsonExtensionDataAttribute]
    public IDictionary<string, object> ExtensionData { get; set; }
}

并反序列化和过滤如下:

var users = JsonSerializer.Deserialize<List<UserObject>>(rawJsonDownload);
users.RemoveAll(u => shouldSkip(u.Id));

return Json(users);

这种方法确保了与过滤相关的属性可以适当地反序列化,而无需对JSON的其余部分做任何假设。尽管这并不像使用LINQ to
JSON那样容易,但是总代码复杂度受筛选检查的复杂度限制,而不是JSON的复杂度。实际上,我的观点是,实际上,这种方法比纯JsonDocument方法更容易使用,因为如果以后需要,它可以更轻松地注入对JSON的修改。

样机小提琴#2 在这里。

没有你选择事情 ,你可能会考虑抛弃WebClientHttpClient,并使用async反序列化。例如:

var httpClient = new HttpClient();
using var usersDocument = await JsonDocument.ParseAsync(await httpClient.GetStreamAsync("WEB API CALL"));

要么

var users = await JsonSerializer.DeserializeAsync<List<UserObject>>(await httpClient.GetStreamAsync("WEB API CALL"));

您还需要将您的API方法转换async为。



 类似资料:
  • 问题内容: 我试图读取Golang中的JSON文件,修改此JSON文件,然后创建一个新的JSON文件/在此JSON文件上进行覆盖。我在网上看到了几个示例,但似乎无法将两个和两个放在一起以获得所需的结果。我尝试只在GO中创建自己的JSON str并对其进行修改,但仍然失败。 我已经尝试过几次读取文件,以下是我的最佳尝试: 这是一个示例输出: 我只是对如何修改我想要的内容感到困惑,特别是上述示例输出的

  • 问题内容: 我正在尝试使用.NET Core 3.0中的新JSON阅读器读取和解析无法容纳在内存中的大JSON文件。 Microsoft的示例代码将a 作为输入 我正在努力寻找的是如何在a中实际使用此代码,并将a 插入a 。 我尝试使用以下代码读取文件,然后 它因错误信息而崩溃 作为参考,这是我使用Newtonsoft.Json的工作代码。 问题答案: 更新2019-10-13: 重写Utf8Js

  • 问题内容: 嗨,我正在尝试从json文件中获取数据,然后插入和ID,然后执行POST REST。我的文件data.json具有: 并且我想添加一个id,以便json数据如下所示: 所以我尝试了: 我无法加载json格式文件。我应该怎么做才能将json文件转换为json对象并添加另一个id值。 问题答案: 使用设置项目。

  • 问题内容: 我想使用Java程序删除文件的某些内容,如下所示。这是在相同文件中替换的写方法,还是应将其复制到另一个文件。 但是它删除了文件的所有内容。 问题答案: 我将从关闭阅读器和刷新书写器开始:

  • 问题内容: 我想根据以下条件在PHP中修改我的xml文件。 我的xml结构如下所示: 现在每次在xml进行修改时,都带有type属性。 意味着,第一次搜索字符串==“ hotels”时,与酒店有关的数据将以上述格式存储在xml文件中。 现在,当再次搜索酒店时,它将删除具有带有值酒店的子元素的元素。 然后在与学校相关的数据附加到xml文件时,进行针对学校的不同查询。与酒店的数据。 现在再次搜索学校已

  • 当然,有关标准的事物是如此之多。有时每个应用程序的配置格式都略有不同, 书写正则表达式来解析和修改所有这些配置文件是一项很烦人的工作。 幸好 Augeas 在这方面可以帮助我们。Augeas 是一个旨在简化使用不同配置文件格式工作的工具, 它将不同格式的配置文件统一呈现为一个简单的包含所有配置项的树状结构。 Puppet 的 Augeas 支持允许你创建 augeas 资源,它可以智能地自动地为所