使用System.Text.Json获取嵌套属性。
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用System.Text.Json获取嵌套属性。相关的知识,希望对你有一定的参考价值。
我正在与 System.Text.Json
在我的项目中,因为我正在处理大文件,所以也决定用它来处理GraphQL响应。
由于GraphQL的性质,有时我会得到高度嵌套的响应,这些响应并不固定,而且映射到一个类也没有意义。 我通常需要检查响应上的一些属性。
我的问题是 JsonElement
. 检查嵌套属性感觉非常笨拙,我觉得应该有更好的方法来解决这个问题。
例如拿我下面的代码来模拟我得到的一个响应。 我只是想检查2个属性是否存在(id & originalSrc),如果存在,就得到它们的值,但感觉就像我把代码做了一顿饭。 有没有更好更清晰更简洁的方法来写这个?
var raw = @"{
""data"": {
""products"": {
""edges"": [
{
""node"": {
""id"": ""gid://shopify/Product/4534543543316"",
""featuredImage"": {
""originalSrc"": ""https://cdn.shopify.com/s/files/1/0286/pic.jpg"",
""id"": ""gid://shopify/ProductImage/146345345339732""
}
}
}
]
}
}
}";
var doc = JsonSerializer.Deserialize<JsonElement>(raw);
JsonElement node = new JsonElement();
string productIdString = null;
if (doc.TryGetProperty("data", out var data))
if (data.TryGetProperty("products", out var products))
if (products.TryGetProperty("edges", out var edges))
if (edges.EnumerateArray().FirstOrDefault().ValueKind != JsonValueKind.Undefined && edges.EnumerateArray().First().TryGetProperty("node", out node))
if (node.TryGetProperty("id", out var productId))
productIdString = productId.GetString();
string originalSrcString = null;
if(node.ValueKind != JsonValueKind.Undefined && node.TryGetProperty("featuredImage", out var featuredImage))
if (featuredImage.TryGetProperty("originalSrc", out var originalSrc))
originalSrcString = originalSrc.GetString();
if (!string.IsNullOrEmpty(productIdString))
{
//do stuff
}
if (!string.IsNullOrEmpty(originalSrcString))
{
//do stuff
}
这不是一个疯狂的代码量,但检查少量的属性是如此的普遍,我希望有一个更干净更易读的方法。
你可以添加几个扩展方法来访问一个子方法。JsonElement
属性名或数组索引的值,如果没有找到,则返回一个可空值。
public static partial class JsonExtensions
{
public static JsonElement? Get(this JsonElement element, string name) =>
element.ValueKind != JsonValueKind.Null && element.ValueKind != JsonValueKind.Undefined && element.TryGetProperty(name, out var value)
? value : (JsonElement?)null;
public static JsonElement? Get(this JsonElement element, int index)
{
if (element.ValueKind == JsonValueKind.Null || element.ValueKind == JsonValueKind.Undefined)
return null;
var value = element.EnumerateArray().ElementAtOrDefault(index);
return value.ValueKind != JsonValueKind.Undefined ? value : (JsonElement?)null;
}
}
现在访问嵌套值的调用可以使用null-conditional操作符连锁在一起。?.
:
var doc = JsonSerializer.Deserialize<JsonElement>(raw);
var node = doc.Get("data")?.Get("products")?.Get("edges")?.Get(0)?.Get("node");
var productIdString = node?.Get("id")?.GetString();
var originalSrcString = node?.Get("featuredImage")?.Get("originalSrc")?.GetString();
Int64? someIntegerValue = node?.Get("Size")?.GetInt64(); // You could use "var" here also, I used Int64? to make the inferred type explicit.
备注。
如果输入的元素不是预期的类型(对象或数组或nullmissing),上述扩展方法将抛出一个异常。 你可以放宽对
ValueKind
如果你不希望在一个意外的值类型上出现异常。有一个开放的API增强请求 为JsonDocumentJsonElement添加JsonPath支持 #31068. 查询通过 JSONPath如果能实现,将使这种事情变得更容易。
演示提琴 此处.
以上是关于使用System.Text.Json获取嵌套属性。的主要内容,如果未能解决你的问题,请参考以下文章
System.Text.Json 反序列化来自 API 调用的嵌套对象 - 数据包装在父 JSON 属性中
System.Text.Json - 将嵌套对象反序列化为字符串
如何使用 System.Text.Json 序列化/反序列化非枚举类型的嵌套字典?
如何反序列化作为 System.Text.Json 中的字符串的嵌套 JSON 对象?