获取“System.Text.Json.JsonElement”不包含“结果”使用 JsonSerializer.DeserializeAsync 进行解析

use*_*862 10 .net c# system.text.json

我的响应中有 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();

            
Run Code Online (Sandbox Code Playgroud)

来自端点的响应实际上有点复杂,我想只提取特定字段,所以我使用了动态

dynamic data = await JsonSerializer.DeserializeAsync<dynamic>(responseBody)

var dataString = data.ToString();
Run Code Online (Sandbox Code Playgroud)

// 数据字符串是

{"result":{"generalInfo":{"firstName":"John","lastName":"Doe"},"isError":false}
Run Code Online (Sandbox Code Playgroud)

如果我尝试访问这样的动态属性

var firstName = data.result.generalInfo.firstName;
var lastName = data.result.generalInfo.lastName;
var isErr = data.IsError;
Run Code Online (Sandbox Code Playgroud)

我遇到异常

“System.Text.Json.JsonElement”不包含“结果”的定义

hal*_*ldo 16

问题不是DeserializeAsync,而是 System.Text.Json 使用JsonElements ,因此动态值实际上是一个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"];
Run Code Online (Sandbox Code Playgroud)

.Net6 中的演示

.Net 6 预览版 v4-6 中添加了对 的支持dynamic,但在最终版本发布之前被删除,以支持JsonNode上述方法。有关更多详细信息,请参阅 github .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() : "";
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,如果可以的话,我的首选方法始终是反序列化为已定义的类,因为它使生活变得更轻松:

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;
Run Code Online (Sandbox Code Playgroud)