You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何遍历API响应的分页数据并将其保存至数据库?

解决API分页数据遍历与数据库存储问题

看起来你遇到的核心问题有两个:无法获取API的总页数,以及硬编码分页循环不生效。咱们一步步来解决:

1. 先搞定总页数的获取

你提到在响应头里找不到总页数,那大概率API把分页元数据(总条目数/总页数)放在了响应内容里,而不是HTTP头中。现在你的GetTrips类只定义了pagepage_sizeitems,需要先确认API返回的完整响应结构——比如用Postman调用一次trips?page=1,看看响应里有没有类似total_items(总条目数)或者total_pages(总页数)的字段。

假设API返回的是total_items,那先更新你的GetTrips类:

public class GetTrips { 
    public int page { get; set; } 
    public int page_size { get; set; } 
    public int total_items { get; set; } // 新增:对应API返回的总条目数
    public Item[] items { get; set; } 
}

如果API直接返回total_pages,那就把total_items换成total_pages即可,后续不用计算总页数。

2. 修复分页遍历逻辑

你之前硬编码i<5不生效,大概率是因为API的页码是从1开始的(很多API都是1-based),而你循环从i=0开始,请求的page=0可能没有数据,导致后续逻辑失效。另外,每次调用CallAPI都新建HttpClient是不好的实践,会耗尽连接池,要复用它。

修改后的完整代码

第一步:复用HttpClient

HttpClient声明为静态字段,避免重复创建:

// 全局复用HttpClient,不要每次调用都new
private static readonly HttpClient _httpClient = new HttpClient();

private static async Task<GetTrips> CallAPI(string endpoint, string accessToken) { 
    var request = new HttpRequestMessage(HttpMethod.Get, new Uri(ApiUri, endpoint)); 
    request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); 

    var response = await _httpClient.SendAsync(request); 
    response.EnsureSuccessStatusCode(); 
    var responseStream = await response.Content.ReadAsStreamAsync(); 
    var responseObject = await JsonSerializer.DeserializeAsync<GetTrips>(responseStream); 

    return responseObject; 
}

第二步:正确遍历所有分页

先请求第一页获取总页数,再循环遍历所有页面:

private static async Task SaveData(string accessToken) { 
    MSSQL_Conn conn = new MSSQL_Conn(conn_string); 

    // 先获取第一页数据,拿到分页元数据
    var firstPage = await CallAPI("trips?page=1", accessToken);
    if (firstPage == null || firstPage.items == null || firstPage.total_items == 0)
    {
        // 没有数据,直接返回
        return;
    }

    // 计算总页数:总条目数 ÷ 每页大小,向上取整
    int totalPages = (int)Math.Ceiling((double)firstPage.total_items / firstPage.page_size);

    // 保存第一页数据
    var firstPageTrips = firstPage.items.Select(s => new Trips { TripID = s.id, VehicleId = s.vehicle });
    // 写入数据库的代码(比如conn.InsertBatch(firstPageTrips);)

    // 循环遍历剩下的页面(从第2页到最后一页)
    for (int page = 2; page <= totalPages; page++) { 
        var currentPage = await CallAPI($"trips?page={page}", accessToken); 
        if (currentPage?.items == null)
        {
            // 当前页无数据,跳过避免空引用
            continue;
        }
        var trips = currentPage.items.Select(s => new Trips { TripID = s.id, VehicleId = s.vehicle }); 
        // 写入数据库的相关代码... 
    } 
}

关键注意点

  • 页码起始值:如果你的API是0-based(页码从0开始),那把循环改成从page=0开始,总页数计算后调整为page < totalPages
  • 错误处理:添加了空值检查,避免因为某一页返回异常导致整个流程崩溃。
  • HttpClient复用:这是.NET中调用API的最佳实践,能提升性能并避免连接泄漏问题。
  • 硬编码失效的原因:之前你循环从0开始,请求的page=0可能没有数据,加上总页数不一定是5,所以循环没覆盖到所有有效数据。

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

火山引擎 最新活动