【问题标题】:How to loop through all pages in a API Rest response如何遍历 API Rest 响应中的所有页面
【发布时间】:2021-05-04 12:17:56
【问题描述】:

我正在编写一个从 WooCommerce 商店检索产品的代码。 API 只返回 100 个产品,而总数达到 147 个。API 返回两个页面,但我似乎无法遍历这些页面。

这是我目前的代码:

protected void btnEnviar_Click(object sender, EventArgs e)
    {
        try
        {
            string apiUrl = "https://thestore.com/wp-json/wc/v3/products?per_page=100";
            string apiUsr = "usertoken";
            string apiPwd = "passwordtoken";

            string urlRequest1 = apiUrl;
            HttpWebRequest requestWeb = (HttpWebRequest)WebRequest.Create(urlRequest1);
            requestWeb.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
            requestWeb.ContentType = "application/json";
            requestWeb.Accept = "application/json";
            requestWeb.Method = WebRequestMethods.Http.Get;
            requestWeb.Headers["Authorization"] = "Basic " + Convert.ToBase64String(Encoding.Default.GetBytes(apiUsr + ":" +apiPwd));
            requestWeb.UseDefaultCredentials = true;
            requestWeb.Proxy.Credentials = CredentialCache.DefaultCredentials;
            HttpWebResponse responseHttpWeb = (HttpWebResponse)requestWeb.GetResponse();

            Stream stream = responseHttpWeb.GetResponseStream();

            //JsonConvert.DeserializeObject<List<RetrieveMultipleResponse>>(JsonStr);
            using (StreamReader reader = new StreamReader(stream))
            {
                Stream webResponse = responseHttpWeb.GetResponseStream();
                string lector = reader.ReadToEnd();
                var mQuery = JsonConvert.DeserializeObject<List<Root>>(lector);
                int contarObjetos = mQuery.Count();
                contarItems.Text = contarObjetos.ToString();

                

                if (contarObjetos == 0)
                {
                    enviado.Text = "No existen registros";
                }
                else
                {
                    
                    foreach (var item in mQuery)
                    {
                        enviado.Text += item.id + ": " + item.name + " - " + item.status + "<br/><hr/>";

                        foreach(var elemento in item.categories)
                        {
                            enviado2.Text += elemento.id + ": " + elemento.name + "<br/><hr/>"; 
                        }
                    }
                    
                }
                
                
            }

        }
        catch (Exception ex)
        {
            enviado.Text = ex.ToString();
        }
        
    }

我已尝试更改 Uri 参数“per_page”,但任何超过 100 的值都会出错。

我可以修改Uri添加一个“page”参数,这样会带上page 1,page 2等:

string apiUrl = "https://antonelly.com.co/wp-json/wc/v3/products?per_page=100&page=2";

但是如何从 api 的标头中获取页数并动态地将其分配给循环?

这是我在 Postman 上看到的标题:

所以我想如果我可以访问该标头并将其分配给一个对象并在每个循环中增加,我将实现我正在寻找的。​​p>

我在https://woocommerce.github.io/woocommerce-rest-api-docs/?python#list-all-products 浏览了 WooCommerce 的 API 文档,但没有关于如何执行此操作的信息,并且在 JSON 的响应中没有返回返回页面数量的对象。

任何帮助对我来说都是巨大的!

【问题讨论】:

  • 你试过responseHttpWeb.Headers吗?例如:string numPages = responseHttpWeb.Headers["X-WP-TotalPages"]; int numPages2; if (int.TryParse(numPages, out numPages2)) { // Success! } 如果给你页数,我可以写几行代码来提取其他页。
  • 是的!它带回了页数(在这种情况下为 2 页)谢谢。但是现在,我该如何循环浏览这些页面?

标签: c# asp.net json api woocommerce


【解决方案1】:

尝试类似:

protected void btnEnviar_Click(object sender, EventArgs e)
{
    try
    {
        string apiUrl = "https://thestore.com/wp-json/wc/v3/products?per_page=100";
        string apiUsr = "usertoken";
        string apiPwd = "passwordtoken";

        int page = 1;
        int totalPages = 0;
        int count = 0;

        do
        {
            string urlRequest = page == 1 ? apiUrl : apiUrl + $"&page={page}";

            HttpWebRequest requestWeb = (HttpWebRequest)WebRequest.Create(urlRequest);

            requestWeb.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
            requestWeb.ContentType = "application/json";
            requestWeb.Accept = "application/json";
            requestWeb.Method = WebRequestMethods.Http.Get;
            requestWeb.Headers["Authorization"] = "Basic " + Convert.ToBase64String(Encoding.Default.GetBytes(apiUsr + ":" + apiPwd));
            requestWeb.UseDefaultCredentials = true;
            requestWeb.Proxy.Credentials = CredentialCache.DefaultCredentials;
            HttpWebResponse responseHttpWeb = (HttpWebResponse)requestWeb.GetResponse();

            string totalPages2 = responseHttpWeb.Headers["X-WP-TotalPages"];

            // We don't really need to check for success. On failure it will write 0 and
            // will break the cycle
            int.TryParse(totalPages2, out totalPages);

            using (var stream = responseHttpWeb.GetResponseStream())
            using (var sr = new StreamReader(stream))
            using (var jr = new JsonTextReader(sr))
            {
                var ser = new JsonSerializer();

                var items = ser.Deserialize<List<Root>>(jr);

                if (items.Count == 0)
                {
                    if (page == 1)
                    {
                        enviado.Text = "No existen registros";
                    }
                }
                else
                {
                    count += items.Count;

                    foreach (var item in items)
                    {
                        enviado.Text += item.id + ": " + item.name + " - " + item.status + "<br/><hr/>";

                        foreach (var elemento in item.categories)
                        {
                            enviado2.Text += elemento.id + ": " + elemento.name + "<br/><hr/>";
                        }
                    }
                }
            }

            page++;
        } while (page <= totalPages);

        contarItems.Text = count.ToString();
    }
    catch (Exception ex)
    {
        enviado.Text = ex.ToString();
        contarItems.Text = string.Empty;
    }
}

页数在页眉中。您可以从responseHttpWeb.Headers["X-WP-TotalPages"] 访问响应标头。然后你必须解析这个数字。您可以将发出请求的整个代码块放在 do-while 循环中,并检查页码 (page) 与总页数 (totalPages)。我们会重新计算 whiletotalPages 的每一“轮”,但这不是问题。

请注意,这些分页查询可能会受到数据库当前更改的影响。如果有人在您对响应进行分页时插入/删除产品,您可能会多次拥有相同的项目(如果它位于第 1 页的末尾并在您下载页面时移至第 2 页),或者您可能会丢失项目(如果某个项目在某处被删除并且所有内容都向上滚动),因此您不应认为从此类网络方法中获得的内容是“完美的”。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-07-07
    • 2014-06-21
    • 1970-01-01
    • 2010-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多