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

2023-12-28

我知道使用 Newtonsoft 可以轻松做到这一点。然而,当我使用 .NET Core 3.0 时,我尝试使用新方法与 JSON 文件交互,即System.Text.Json——我拒绝相信我正在尝试做的事情有那么困难!

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

由于我最终会在流程结束时返回另一个 JSON,因此我不想将其反序列化为模型。请注意 API 中的数据结构could改变,但它会always有一个密钥,我可以通过它与我的数据库记录进行比较。

我的代码目前如下所示:

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

这似乎是一个lot为了实现对 Newtonsoft 来说相当微不足道的事情,需要跳过重重困难。

任何人都可以建议我更好的方法来做到这一点 - 并且,理想情况下,不需要UserObject?


您的问题是您想要检索、过滤和传递一些 JSON,而不需要为该 JSON 定义完整的数据模型。通过 Json.NET,您可以使用LINQ 到 JSON https://www.newtonsoft.com/json/help/html/LINQtoJSON.htm以此目的。你的问题是,目前可以轻松解决这个问题吗System.Text.Json?

从 .NET 6 开始,这不能通过以下方式轻松完成System.Text.Json因为它不支持JSONPath https://goessner.net/articles/JsonPath/这在此类应用中通常非常方便。目前有一个未解决的问题将 JsonPath 支持添加到 JsonDocument/JsonElement #41537 https://github.com/dotnet/corefx/issues/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在你的问题中。你有什么选择?

在 .NET 6 及更高版本中,您可以将 JSON 解析为JsonNode https://learn.microsoft.com/en-us/dotnet/api/system.text.json.nodes.jsonnode?view=net-6.0,编辑其内容,并返回修改后的 JSON。 A JsonNode代表一个editable https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-use-dom-utf8jsonreader-utf8jsonwriter?pivots=dotnet-6-0#create-a-jsonnode-dom-with-object-initializers-and-make-changesJSON 文档对象模型,因此与 Newtonsoft 的最接近JToken https://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_Linq_JToken.htm等级制度。

以下代码显示了这样的示例:

var root = JsonNode.Parse(rawJsonDownload).AsArray(); // AsArray() throws if the root node is not an array.
for (int i = root.Count - 1; i >= 0; i--)
{
    if (shouldSkip(root[i].AsObject()["id"].GetValue<long>()))
        root.RemoveAt(i);
}

return Json(root);

样机小提琴#1here https://dotnetfiddle.net/HGRDeT

在 .NET Core 3.x 及更高版本中,您可以解析为JsonDocument https://learn.microsoft.com/en-us/dotnet/api/system.text.json.jsondocument并返回一些过滤后的集合JsonElement https://learn.microsoft.com/en-us/dotnet/api/system.text.json.jsonelement nodes。如果过滤逻辑非常简单并且您不需要以任何其他方式修改 JSON,那么这种方法效果很好。但请注意以下限制JsonDocument:

  • JsonDocument and JsonElement是只读的。它们只能用于examineJSON 值,不修改或创建 JSON 值。

  • JsonDocument是一次性的,实际上必须需要处理最大限度地减少高使用场景中垃圾收集器 (GC) 的影响,根据docs https://learn.microsoft.com/en-us/dotnet/api/system.text.json.jsondocument?view=netcore-3.0#remarks。为了返回一个JsonElement你必须clone https://learn.microsoft.com/en-us/dotnet/api/system.text.json.jsonelement.clone?view=netcore-3.0#System_Text_Json_JsonElement_Clone it.

问题中的过滤场景很简单,可以使用以下代码:

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

模型小提琴#2here https://dotnetfiddle.net/rO10rE.

在任何版本中,您都可以创建一个partial仅反序列化过滤所需的属性的数据模型,其余 JSON 绑定到[JsonExtensionDataAttribute] https://learn.microsoft.com/en-us/dotnet/api/system.text.json.serialization.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 的修改。

模型小提琴#3here https://dotnetfiddle.net/eDvr7K.

无论你选择哪一个,你可能会考虑放弃WebClient for HttpClient https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient?view=netcore-3.0并使用async反序列化。例如。:

var httpClient = new HttpClient(); // Cache statically and reuse in production
var root = await httpClient.GetFromJsonAsync<JsonArray>("WEB API CALL");

Or

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

Or

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

你需要convert https://stackoverflow.com/a/41453278/3744182你的API方法是async以及。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 System.Text.Json 修改 JSON 文件 的相关文章

  • 按成员序列化

    我已经实现了template
  • 在结构中使用 typedef 枚举并避免类型混合警告

    我正在使用 C99 我的编译器是 IAR Embedded workbench 但我认为这个问题对于其他一些编译器也有效 我有一个 typedef 枚举 其中包含一些项目 并且我向该新类型的结构添加了一个元素 typedef enum fo
  • 秒表有最长运行时间吗?

    多久可以Stopwatch在 NET 中运行 如果达到该限制 它会回绕到负数还是从 0 重新开始 Stopwatch Elapsed返回一个TimeSpan From MSDN https learn microsoft com en us
  • asp.net core / kestrel中的线程管理

    我正在解决我们已迁移到 asp net core 2 0 的 asp net 应用程序的性能 可扩展性问题 我们的应用程序作为应用程序服务托管在 azure 上 并且在任何中等流量的情况下都很容易崩溃 让我困惑的一件事是如何处理多个并发请求
  • 查找c中结构元素的偏移量

    struct a struct b int i float j x struct c int k float l y z 谁能解释一下如何找到偏移量int k这样我们就可以找到地址int i Use offsetof 找到从开始处的偏移量z
  • BitTorrent 追踪器宣布问题

    我花了一点业余时间编写 BitTorrent 客户端 主要是出于好奇 但部分是出于提高我的 C 技能的愿望 我一直在使用理论维基 http wiki theory org BitTorrentSpecification作为我的向导 我已经建
  • OleDbDataAdapter 未填充所有行

    嘿 我正在使用 DataAdapter 读取 Excel 文件并用该数据填充数据表 这是我的查询和连接字符串 private string Query SELECT FROM Sheet1 private string ConnectStr
  • Clang 3.1 + libc++ 编译错误

    我已经构建并安装了 在前缀下 alt LLVM Clang trunk 2012 年 4 月 23 日 在 Ubuntu 12 04 上成功使用 GCC 4 6 然后使用此 Clang 构建的 libc 当我想使用它时我必须同时提供 lc
  • 如何格式化 Json 输出

    请帮助我如何获取 JSON 输出 如下所示 costMethod Average fundingDate 2008 10 02 fundingAmount 2510959 95 代替 type sma costMethod Average
  • C# 中通过 Process.Kill() 终止的进程的退出代码

    如果在我的 C 应用程序中 我正在创建一个可以正常终止或开始行为异常的子进程 在这种情况下 我通过调用 Process Kill 来终止它 但是 我想知道该进程是否已退出通常情况下 我知道我可以获得终止进程的错误代码 但是正常的退出代码是什
  • C++ OpenSSL 导出私钥

    到目前为止 我成功地使用了 SSL 但遇到了令人困惑的障碍 我生成了 RSA 密钥对 之前使用 PEM write bio RSAPrivateKey 来导出它们 然而 手册页声称该格式已经过时 实际上它看起来与通常的 PEM 格式不同 相
  • 显示UnityWebRequest的进度

    我正在尝试使用下载 assetbundle统一网络请求 https docs unity3d com ScriptReference Networking UnityWebRequest GetAssetBundle html并显示进度 根
  • while 循环中的 scanf

    在这段代码中 scanf只工作一次 我究竟做错了什么 include
  • 转发声明和包含

    在使用库时 无论是我自己的还是外部的 都有很多带有前向声明的类 根据情况 相同的类也包含在内 当我使用某个类时 我需要知道该类使用的某些对象是前向声明的还是 include d 原因是我想知道是否应该包含两个标题还是只包含一个标题 现在我知
  • 控件的命名约定[重复]

    这个问题在这里已经有答案了 Microsoft 在其网站上提供了命名指南 here http msdn microsoft com en us library xzf533w0 VS 71 aspx 我还有 框架设计指南 一书 我找不到有关
  • Windows 窗体:如果文本太长,请添加新行到标签

    我正在使用 C 有时 从网络服务返回的文本 我在标签中显示 太长 并且会在表单边缘被截断 如果标签不适合表单 是否有一种简单的方法可以在标签中添加换行符 Thanks 如果您将标签设置为autosize 它会随着您输入的任何文本自动增长 为
  • WPF/C# 将自定义对象列表数据绑定到列表框?

    我在将自定义对象列表的数据绑定到ListBox in WPF 这是自定义对象 public class FileItem public string Name get set public string Path get set 这是列表
  • 将控制台重定向到 .NET 程序中的字符串

    如何重定向写入控制台的任何内容以写入字符串 对于您自己的流程 Console SetOut http msdn microsoft com en us library system console setout aspx并将其重定向到构建在
  • 是否可以在 .NET Core 中将 gRPC 与 HTTP/1.1 结合使用?

    我有两个网络服务 gRPC 客户端和 gRPC 服务器 服务器是用 NET Core编写的 然而 客户端是托管在 IIS 8 5 上的 NET Framework 4 7 2 Web 应用程序 所以它只支持HTTP 1 1 https le
  • C# 模拟VolumeMute按下

    我得到以下代码来模拟音量静音按键 DllImport coredll dll SetLastError true static extern void keybd event byte bVk byte bScan int dwFlags

随机推荐

  • .NET 中的类数量?

    NET 中的类总数是多少 那个数字 位于下载的 NET 2 0 NET 3 0 和 NET 运行时中 3 5 SP1 我们正在写一篇关于应用程序的科学论文 基于 NET 目前声明还有更多 超过6000个班级 但我不确定这是否正确 数字 例如
  • Antlr 外部输入

    我有一个语法文件 BoardFile g4 其中包含 仅相关部分 grammar Board Tokens GADGET squareBumper circleBumper triangleBumper leftFlipper rightF
  • 如何为 UIWebView 设置自定义键盘

    如何为 iOS7 及更高版本的可编辑 UIWebView 显示自定义键盘和输入附件视图 即 我如何设置并使用其中的值 UIWebView setInputView and UIWebView setInputAccessoryView 了解
  • Google Contacts API - 获取访问令牌(oauth)后

    我设法获取谷歌联系人 API 的访问令牌 但是当我尝试调用以检索登录用户的个人资料时 我收到 401 未经授权的错误 我做了一些研究 并按照 各种 谷歌文档中提到的步骤进行操作 例如this one http code google com
  • gremlin-python 不是可用的 GremlinScriptEngine

    我正在尝试使用 gremlin python 在 AWS neptune 上执行 lambda 函数 它击中了我gremlin python is not an available GremlinScriptEngine 有人可以帮忙解决这
  • Java 比较器 Arrays.sort()

    我想排序一个arrayJava中的二维数组根据一些规则 比如说距原点的距离 我看到了几种使用方法Arrays sort 1 Arrays sort points Comparator comparing p gt p 0 p 0 p 1 p
  • 如何在react中使用信号协议

    如何在 React 中使用信号协议 I used npm libsignal但即使这样我在node modules 中也遇到了错误 我尝试使用libsignal protocol js文件来自 https github com signal
  • 您可以使用 Cloud Formation 创建使用计划吗?

    就像标题中一样 我可以仅使用 Cloud Formation 在 AWS 上部署内容 现在 我尝试使用 API 密钥来保护我的 API 网关 看起来我需要一个使用计划 这里的文档似乎没有涵盖它 http docs aws amazon co
  • 如何创建属性包含点(句点)的 json 字符串?

    我正在尝试发送HttpRequest它需要一个像这样的 JSON 对象 some setting withperiods myvalue 我一直在为其他请求创建匿名对象 但我无法对这个请求执行此操作 因为名称包含一个点 我知道我可以创建一个
  • phpunit - 需要有关有风险的测试的帮助

    我正在为一个网站实施一些测试 在一次特定的测试中 出现了这样的结果 event test suite Example V test test Example V test test 3 status error time 13 469105
  • 如何从命令行编译 MSVC 项目中的单个源文件?

    我即将开始对我们的构建进行一些基准测试 测试 并且我想从命令行驱动整个过程 我知道DevEnv但我不相信它可以做我想做的事 如果我可以在单个项目中构建单个文件 我会很高兴 这可以做到吗 其神奇咒语如下 请注意 这仅在 VS 2010 上进行
  • Azure CloudBlockBlob.DeleteIfExists() - false 是否始终意味着 blob 不存在?

    我知道如果 blob 存在 CloudBlockBlob DeleteIfExists 返回 true 如果不存在则返回 false 不过 我很好奇 如果 blob 确实存在 但 Azure 中出现问题 导致文件删除无法发生 我找不到有关该
  • Angular 2 路由器中间的通配符选择器

    我正在尝试使用 Angular js 2 开发一个项目 我正在尝试使用路由器 我正在尝试创建一条带有参数的路线来捕获如下内容 m SOMETHING1 c SOME THING2 p SOMETHING3 请注意 SOME THING2 是
  • Python 贝叶斯信念网络分类器

    谁能推荐一个用 Python 实现的贝叶斯信念网络分类器 它可以根据描述多个相互关联对象的一系列事实的稀疏网络的输入生成信念概率 例如鉴于 FOL 中表述的事实 X 饿了 是一只猴子 正在吃东西 如下所示 isHungry x isMonk
  • 简单设置关闭显示:none / block with javascript

    我有以下代码 table tr class odd td Entry 1 td tr tr class even clickable td gt Entry 2 td tr tr class even td ul li Informatio
  • Spring Rest 模板中的哑剧类型无效?

    我只是想发出一个简单的 REST 请求 如下所示 String url some url MultiValueMap
  • 尝试通过 --experimental-loader 选项使用 mocha、ES6 模块和 ts-node

    我正在尝试获取 ts node 选项 experimental loader与摩卡一起工作 但运气不佳 在我开始尝试编译 ES6 模块之前 我曾经能够通过这种方式运行 mocha 测试 test nyc reporter html moch
  • 如何动态添加和加载入口点?

    我正在开发一个带有使用入口点的插件的 Slack 机器人 我想在运行时动态添加插件 我有一个具有以下结构的项目 my project dir my projects python code plugins plugin1 py plugin
  • @Consumes 不适用于 JSON

    我有以下休息服务 Path add POST Consumes MediaType APPLICATION JSON public Response add SomeEntity entity entity someService addE
  • 使用 System.Text.Json 修改 JSON 文件

    我知道使用 Newtonsoft 可以轻松做到这一点 然而 当我使用 NET Core 3 0 时 我尝试使用新方法与 JSON 文件交互 即System Text Json 我拒绝相信我正在尝试做的事情有那么困难 我的应用程序需要列出尚未