Lou*_*les 15 c# json asp.net-core asp.net-core-3.0 system.text.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);
}
Run Code Online (Sandbox Code Playgroud)
为了实现对 Newtonsoft 来说相当微不足道的东西,这似乎有很多障碍需要跳过。
任何人都可以建议我这样做的更好方法 - 理想情况下,不需要UserObject?
dbc*_*dbc 34
您的问题是您希望检索、过滤和传递一些 JSON,而无需为该 JSON 定义完整的数据模型。借助 Json.NET,您可以为此目的使用LINQ to JSON。您的问题是,目前可以使用 轻松解决这个问题System.Text.Json吗?
从 .NET Core 3.0 开始,这不能很容易地完成,System.Text.Json因为:
JsonDocument,对应于JToken或的类型XDocument是只读的。它只能用于检查JSON 值,不能用于修改或创建 JSON 值。
目前有一个未解决的问题Writable Json DOM #39922跟踪此问题。
System.Text.Json不支持JSONPath,这在此类应用程序中通常非常方便。
目前有一个未解决的问题Add JsonPath support to JsonDocument/JsonElement #41537跟踪这个。
话虽如此,假设您有以下 JSON:
[
{
"id": 1,
"name": "name 1",
"address": {
"Line1": "line 1",
"Line2": "line 2"
},
// More properties omitted
}
//, Other array entries omitted
]
Run Code Online (Sandbox Code Playgroud)
以及一些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);
Run Code Online (Sandbox Code Playgroud)
样机小提琴 #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; }
}
Run Code Online (Sandbox Code Playgroud)
并反序列化和过滤如下:
var users = JsonSerializer.Deserialize<List<UserObject>>(rawJsonDownload);
users.RemoveAll(u => shouldSkip(u.Id));
return Json(users);
Run Code Online (Sandbox Code Playgroud)
这种方法确保可以适当地反序列化与过滤相关的属性,而无需对 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"));
Run Code Online (Sandbox Code Playgroud)
或者
var users = await JsonSerializer.DeserializeAsync<List<UserObject>>(await httpClient.GetStreamAsync("WEB API CALL"));
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7534 次 |
| 最近记录: |