获取 'System.Text.Json.JsonElement' 不包含 'result' 解析为 JsonSerializer.DeserializeAsync
getting 'System.Text.Json.JsonElement' does not contain 'result' Parsing with JsonSerializer.DeserializeAsync
我JSON的回复结构如下
{
"statusCode": 200,
"result": {
"generalInfo": {
"firstName": "",
"lastName": ""
},
"isError": false
},
"sentDate": "2022-02-06T10:04:06.6853775Z",
}
var response = await _httpClient.PostAsJsonAsync(address, model);
Stream responseBody = await response.Content.ReadAsStreamAsync();
端点的响应实际上有点复杂,我只想提取特定字段,所以我使用了动态
dynamic data = await JsonSerializer.DeserializeAsync<dynamic>(responseBody)
var dataString = data.ToString();
// dataString 是
{"result":{"generalInfo":{"firstName":"John","lastName":"Doe"},"isError":false}
如果我尝试像这样访问动态属性
var firstName = data.result.generalInfo.firstName;
var lastName = data.result.generalInfo.lastName;
var isErr = data.IsError;
我遇到异常
'System.Text.Json.JsonElement' does not contain a definition for
'result'
问题不在于DeserializeAsync
,而是System.Text.Json使用了JsonElement
s,所以动态值实际上是一个JsonElement
。您需要解析来自 JsonElement
.
的数据
但是,如果您使用的是 .Net 6,则可以使用 JsonNode
:
// deserialize into JsonNode
JsonNode data = await JsonSerializer.DeserializeAsync<JsonNode>(responseBody);
// OR parse the json string
JsonNode data = JsonNode.Parse(dataString);
int statusCode = (int)data["statusCode"];
var firstName = (string)data["result"]["generalInfo"]["firstName"];
var lastName = (string)data["result"]["generalInfo"]["lastName"];
var isErr = (bool)data["result"]["isError"];
对 dynamic
的支持已添加到 .Net 6 预览版 v4-6 中,但在最终发布之前已被删除,以支持上述 JsonNode
方法。有关详细信息,请参阅 github What's new in .NET 6 Preview 7。
否则,您可以手动解析它:
bool isError = false;
string firstName = "";
string lastName = "";
if (data is JsonElement elt && elt.TryGetProperty("result", out elt))
{
isError = elt.TryGetProperty("isError", out JsonElement boolElt) ? boolElt.GetBoolean() : false;
if (elt.TryGetProperty("generalInfo", out var genInfo))
{
firstName = genInfo.TryGetProperty("firstName", out var firstElt) ? firstElt.GetString() : "";
lastName = genInfo.TryGetProperty("lastName", out var lastElt) ? lastElt.GetString() : "";
}
}
但是,如果可以的话,我的首选方法总是反序列化为已定义的 类,因为这会让生活变得更轻松:
public class GeneralInfo
{
public string firstName { get; set; }
public string lastName { get; set; }
}
public class Result
{
public GeneralInfo generalInfo { get; set; }
public bool isError { get; set; }
}
public class Root
{
public Result result { get; set; }
}
var data = await JsonSerializer.DeserializeAsync<Root>(responseBody);
var firstName = data.result.generalInfo.firstName;
我JSON的回复结构如下
{
"statusCode": 200,
"result": {
"generalInfo": {
"firstName": "",
"lastName": ""
},
"isError": false
},
"sentDate": "2022-02-06T10:04:06.6853775Z",
}
var response = await _httpClient.PostAsJsonAsync(address, model);
Stream responseBody = await response.Content.ReadAsStreamAsync();
端点的响应实际上有点复杂,我只想提取特定字段,所以我使用了动态
dynamic data = await JsonSerializer.DeserializeAsync<dynamic>(responseBody)
var dataString = data.ToString();
// dataString 是
{"result":{"generalInfo":{"firstName":"John","lastName":"Doe"},"isError":false}
如果我尝试像这样访问动态属性
var firstName = data.result.generalInfo.firstName;
var lastName = data.result.generalInfo.lastName;
var isErr = data.IsError;
我遇到异常
'System.Text.Json.JsonElement' does not contain a definition for 'result'
问题不在于DeserializeAsync
,而是System.Text.Json使用了JsonElement
s,所以动态值实际上是一个JsonElement
。您需要解析来自 JsonElement
.
但是,如果您使用的是 .Net 6,则可以使用 JsonNode
:
// deserialize into JsonNode
JsonNode data = await JsonSerializer.DeserializeAsync<JsonNode>(responseBody);
// OR parse the json string
JsonNode data = JsonNode.Parse(dataString);
int statusCode = (int)data["statusCode"];
var firstName = (string)data["result"]["generalInfo"]["firstName"];
var lastName = (string)data["result"]["generalInfo"]["lastName"];
var isErr = (bool)data["result"]["isError"];
对 dynamic
的支持已添加到 .Net 6 预览版 v4-6 中,但在最终发布之前已被删除,以支持上述 JsonNode
方法。有关详细信息,请参阅 github What's new in .NET 6 Preview 7。
否则,您可以手动解析它:
bool isError = false;
string firstName = "";
string lastName = "";
if (data is JsonElement elt && elt.TryGetProperty("result", out elt))
{
isError = elt.TryGetProperty("isError", out JsonElement boolElt) ? boolElt.GetBoolean() : false;
if (elt.TryGetProperty("generalInfo", out var genInfo))
{
firstName = genInfo.TryGetProperty("firstName", out var firstElt) ? firstElt.GetString() : "";
lastName = genInfo.TryGetProperty("lastName", out var lastElt) ? lastElt.GetString() : "";
}
}
但是,如果可以的话,我的首选方法总是反序列化为已定义的 类,因为这会让生活变得更轻松:
public class GeneralInfo
{
public string firstName { get; set; }
public string lastName { get; set; }
}
public class Result
{
public GeneralInfo generalInfo { get; set; }
public bool isError { get; set; }
}
public class Root
{
public Result result { get; set; }
}
var data = await JsonSerializer.DeserializeAsync<Root>(responseBody);
var firstName = data.result.generalInfo.firstName;