c# API GET 请求分页记录时,如何处理“未找到给定的标头”?

问题描述 投票:0回答:1

我正在从一个 API 请求数据,该 API 需要基于名为“cursor”的自定义标头的分页记录。每次调用只能检索 100 条记录,因此我创建了一个 while 循环来执行。循环起作用......直到它不起作用为止。一旦所有记录都被分页,标题就会被删除,我的程序会出现错误:

“未找到给定的标头。”

我的数据库中不会发生任何插入操作,因为请求会一直流式传输,直到全部分页为止。

我该如何处理这个问题以使程序成功完成?

拨打的电话是:

var products = await ProcessProducts(userAndPasswordToken, BaseUrl);

被调用的任务:

    private static async Task<List<Products>> ProcessProducts(string userAndPasswordToken, string BaseUrl)
    {
        //Construct urls
        string RequestPath = string.Format("food/products");
        string FullUrl = string.Format("{0}{1}", BaseUrl, RequestPath);
        string CursorPath = string.Format("");

        //Use GetAsync instead of GetStreamAsync unless it's mandatory for your codebase.
        var response = await client.GetAsync(FullUrl);

        //Extract string from the response right away
        var content = await response.Content.ReadAsStringAsync();

        //Pass it in instead of Steam.
        var Products = Newtonsoft.Json.JsonConvert.DeserializeObject<List<Products>>(content);

        //Place the header key mapped with the cursor value.
        IEnumerable<string> values = response.Headers.GetValues("cursor");

        // string cursor = null;
        string cursor = "4146";
        // cursor = values?.FirstOrDefault();
        do
        {

            CursorPath = $"?cursor={cursor}";
            if (cursor == null) CursorPath = string.Format("");
            FullUrl = string.Format("{0}{1}{2}", BaseUrl, RequestPath, CursorPath);
            response = await client.GetAsync(FullUrl);
            content = await response.Content.ReadAsStringAsync();
            var nextProducts = Newtonsoft.Json.JsonConvert.DeserializeObject<List<Products>>(content);

            // add Products in the next page.
            Products.AddRange(nextProducts);

            values = response.Headers.GetValues("cursor");
            cursor = values?.FirstOrDefault();

            System.Threading.Thread.Sleep(1000);
            Console.WriteLine(FullUrl);
            Console.WriteLine(response);

        } while (cursor != null);

        return Products;
    }

插入是通过 SQL 存储过程进行的:

            using (SqlConnection conn = new SqlConnection(lConnString))
            {
                conn.Open();
                using (TransactionScope ts = new TransactionScope())
                {

                    foreach (var repo in products)
                    {
                        SqlCommand cmdIns = new SqlCommand("usp_insert_Products", conn);
                        cmdIns.CommandType = CommandType.StoredProcedure;
                        cmdIns.Parameters.AddWithValue("@ProductId", repo.ProductId.ToString() ?? (object)DBNull.Value);
                        cmdIns.Parameters.AddWithValue("@ProductDetailId", repo.ProductDetailId.ToString() ?? (object)DBNull.Value);
                        cmdIns.ExecuteNonQuery();
                    }

                    ts.Complete();
                }
                conn.Close();

我提供的示例代码有一个完全不同的方法,如果我无法让我的代码正常运行,我正处于转向的边缘:

示例代码

// Paging is handled by making a request and then making
// follow up requests as long as a "cursor" is returned.
string cursor = null;
do
{
    var query = HttpUtility.ParseQueryString("");
    query["locationId"] = "1";
    query["businessDate"] = "2019-04-30";
    if (cursor != null) query["cursor"] = cursor;

    var fullUrl = $"{url}/{endpoint}?{query}";
    _testOutputHelper.WriteLine(fullUrl);
    var json = client.DownloadString(fullUrl);
    results.AddRange(
        JsonConvert.DeserializeObject<List<Check>>(json));

    cursor = client.ResponseHeaders["cursor"];
} while (cursor != null);
}
c# pagination get http-headers
1个回答
3
投票

如果找不到标头,您正在使用

response.Headers.GetValues("cursor")
(已记录)抛出 InvalidOperationException

您应该使用

TryGetValues

 来代替:

if (response.Headers.TryGetValues("cursor", out IEnumerable<string> values)) { // header exists } else { // header doesn't exist }
    
© www.soinside.com 2019 - 2024. All rights reserved.