咨询区

  • Hexxed

我现在有这样的一串json。

{
"count": 3,
"value": [
{
"id": "AAAAAAAAAAAAA",
"description": "test1",
"name": "name1"
},
{
"id": "BBBBBBBBBB",
"description": "test2",
"name": "name2"
},
{
"id": "CCCCCCCCCCCC",
"description": "test3",
"name": "name3"
}
]
}

这个json是我调用对方的 API 获得的,现在我想通过 LINQ 从这个json中提取指定的值,比如说提取 ​​name1​​,也有可能是 ​​id,description,name​​。

我想到了用下面的方法去提取。

dynamic json = JObject.Parse(client.GetString().Result);

但我觉得这种写法不是很友好,不知道大家在这种场景下是否有更好的处理方式?

回答区

  • Rui Jarimba

在我的项目中,我是将 json 反序列化为 C# 的 Objects,然后在 Objects 上使用 Linq 去检索,比如下面的类定义。

public class Content
{
[JsonProperty("count")]
public int Count { get; set; }

[JsonProperty("value")]
public List<Value> Values { get; set; }

public Content()
{
Values = new List<Value>();
}
}

public class Value
{
[JsonProperty("id")]
public string Id { get; set; }

[JsonProperty("description")]
public string Description { get; set; }

[JsonProperty("name")]
public string Name { get; set; }
}

下面是反序列化的写法。

public class Content
{
[JsonProperty("count")]
public int Count { get; set; }

[JsonProperty("value")]
public List<Value> Values { get; set; }

public Content()
{
Values = new List<Value>();
}
}

public class Value
{
[JsonProperty("id")]
public string Id { get; set; }

[JsonProperty("description")]
public string Description { get; set; }

[JsonProperty("name")]
public string Name { get; set; }
}

点评区

以小编个人来说,最通用的做法就是将 json 转成 model 实体后再进行检索过滤,但很多时候,你的对接方可能是解释性语言 ​​(nodejs,python)​​​,这就意味着别人给你的json是动态变化的,如果遇到这种需求的化,可以使用 ​​JObject​​ 去处理,比如下面的代码。

  public async Task<List<EmployeeSearchResponse>> EmployeeSearch(AuthModel auth, EmployeeSearchRequest request)
{
var query = await Policy.Handle<TokenFailException>().RetryAsync(1, async (ex, count) =>
{
await Login(auth);

}).ExecuteAsync(async () =>
{
var requestBody = CreateRequest(request, auth);

var responseBody = await httpClient.PostAsync(employeecard_search_url, requestBody);

ThrowIfTokenInvaid(responseBody);

var response = JsonConvert.DeserializeObject<XiResponse<List<EmployeeSearchResponse>>>(responseBody);

return response.Data;
});

return query;
}

public void ThrowIfTokenInvaid(string responseBody)
{
var jobject = JsonConvert.DeserializeObject<JObject>(responseBody);

var code = jobject["code"].Value<int>();

if (code == 205 || code == 206) throw new TokenFailException("xxx");
}