You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 6中如何解析HttpClient返回的HttpResponse并提取指定字段?

问题解决:从API响应中提取指定字段

你当前的问题是反序列化时用了object类型,导致Newtonsoft.Json无法正确解析响应的复杂JSON结构,生成了错误的空嵌套数组对象。而直接返回的响应字符串是正确的,包含Id、Login等目标字段。以下是几种可行的解决方法:

方法一:创建强类型实体类(推荐)

根据响应的JSON结构,定义对应的实体类,反序列化后可直接通过属性访问字段:

实体类定义

// 根响应类
public class ApiResponse
{
    public bool HasError { get; set; }
    public string AlertType { get; set; }
    public string AlertMessage { get; set; }
    public List<string> ModelErrors { get; set; }
    public DataContainer Data { get; set; }
}

// Data容器类
public class DataContainer
{
    public int Count { get; set; }
    public List<UserInfo> Objects { get; set; }
}

// 用户信息类(包含需要的目标字段)
public class UserInfo
{
    public long Id { get; set; }
    public string CurrencyId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string MiddleName { get; set; }
    public string Login { get; set; }
}

修改后的API调用方法

using LoggerApi.Methods;
using System;
using System.Net.Http;
using System.Text;
using Newtonsoft.Json;
using System.Threading.Tasks;
using System.Linq;

namespace LoggerApi.Methods
{
    public class ApiMethods
    {
        public async static Task<UserInfo> GetClientInformations(string authenticationCode, string username = "username")
        {
            // 注意:HttpClient应复用,避免每次创建新实例
            using var client = new HttpClient();
            var userInformationEndpoint = new Uri("https://myurl.com/url");
            var userInformationPayload = new UserInformationPayload()
            {
                Login = username
            };
            var serializePayload = JsonConvert.SerializeObject(userInformationPayload);
            var payload = new StringContent(serializePayload, Encoding.UTF8, "application/json");
            
            // 直接await异步请求,避免.Result阻塞
            var response = await client.PostAsync(userInformationEndpoint, payload);
            response.EnsureSuccessStatusCode(); // 确保请求成功
            var res = await response.Content.ReadAsStringAsync();
            
            var apiResponse = JsonConvert.DeserializeObject<ApiResponse>(res);
            // 返回第一个用户信息(响应中Count为1)
            return apiResponse.Data?.Objects?.FirstOrDefault();
        }
    }
}

方法二:使用dynamic动态类型

若不想定义实体类,可通过dynamic类型直接访问字段:

public async static Task<object> GetClientInformations(string authenticationCode, string username = "username")
{
    using var client = new HttpClient();
    var userInformationEndpoint = new Uri("https://myurl.com/url");
    var userInformationPayload = new UserInformationPayload()
    {
        Login = username
    };
    var serializePayload = JsonConvert.SerializeObject(userInformationPayload);
    var payload = new StringContent(serializePayload, Encoding.UTF8, "application/json");
    
    var response = await client.PostAsync(userInformationEndpoint, payload);
    response.EnsureSuccessStatusCode();
    var res = await response.Content.ReadAsStringAsync();
    
    dynamic apiResponse = JsonConvert.DeserializeObject(res);
    // 提取需要的字段并返回匿名对象
    return new 
    {
        Id = apiResponse.Data.Objects[0].Id,
        Login = apiResponse.Data.Objects[0].Login,
        FirstName = apiResponse.Data.Objects[0].FirstName,
        LastName = apiResponse.Data.Objects[0].LastName
    };
}

方法三:使用JObject解析(Newtonsoft.Linq)

通过LINQ to JSON直接查询目标字段:

using Newtonsoft.Json.Linq;

public async static Task<(long Id, string Login, string FirstName, string LastName)> GetClientInformations(string authenticationCode, string username = "username")
{
    using var client = new HttpClient();
    var userInformationEndpoint = new Uri("https://myurl.com/url");
    var userInformationPayload = new UserInformationPayload()
    {
        Login = username
    };
    var serializePayload = JsonConvert.SerializeObject(userInformationPayload);
    var payload = new StringContent(serializePayload, Encoding.UTF8, "application/json");
    
    var response = await client.PostAsync(userInformationEndpoint, payload);
    response.EnsureSuccessStatusCode();
    var res = await response.Content.ReadAsStringAsync();
    
    JObject apiResponse = JObject.Parse(res);
    // 定位到第一个用户对象
    JToken userToken = apiResponse["Data"]["Objects"][0];
    
    // 提取字段并返回元组
    long id = userToken["Id"].Value<long>();
    string login = userToken["Login"].Value<string>();
    string firstName = userToken["FirstName"].Value<string>();
    string lastName = userToken["LastName"].Value<string>();
    
    return (id, login, firstName, lastName);
}

额外注意点

  • HttpClient复用:不要每次调用都创建新的HttpClient实例,ASP.NET Core项目建议使用IHttpClientFactory,避免socket耗尽问题。
  • 错误处理:response.EnsureSuccessStatusCode()会在请求失败时抛出异常,可根据业务需求添加try-catch逻辑。
  • 原代码问题:之前用client.PostAsync(...).Result会导致异步阻塞,应替换为直接await异步方法。

内容的提问来源于stack exchange,提问作者imuzz01

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 21:01:36