使用System.Text.Json修改JSON文件
我知道您可以使用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。您的问题是,
从.NET Core 3.0开始,System.Text.Json
由于以下原因,此操作无法如此轻松地完成:
JsonDocument
,对应于JToken
或的类型XDocument
为只读。它只能用于 检查 JSON值,不能用于修改或创建JSON值。
当前有一个未解决的问题 Writable Json
DOM#39922对此进行了 跟踪。
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
。您有什么选择?
。如果过滤逻辑非常简单,并且您不需要以任何其他方式修改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 在这里。
这应该使您无需硬编码整个数据模型即可实施必要的过滤。
为此,请定义以下模型:
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 在这里。
,你可能会考虑抛弃WebClient
了HttpClient
,并使用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
为。
以上是 使用System.Text.Json修改JSON文件 的全部内容, 来源链接: utcz.com/qa/432196.html