Api响应列表/从api响应中获取所有数据

时间:2019-10-25 15:04:21

标签: list api asp.net-core

.netcore mvc架构是我的新手。我正在尝试使用api数据响应,到目前为止,我已经成功获取了数据,但是我面临的问题是api响应/结果大于一个时。例如,如果实际的api响应为以下

  "responseHeader":{
    "status":0,
    "QTime":0,
    "params":{
      "q":"title:\"A\""}},
  "response":{"numFound":3,"start":0,"docs":[
      {
        "date":"1970-01-01T00:00:00Z",
        "tstamp":"2019-11-22T12:22:31.698Z",
        "digest":"e23d679991d80d832504e7395d139fe4",
        "contentLength":"25476",
        "boost":0.0,

       "title":["emb- A1]
        "url":"https://www.example.com/a/b/c0/"},
{
        "date":"1970-01-01T00:00:00Z",
        "tstamp":"2019-11-22T12:22:31.698Z",
        "digest":"e23d679991d80d832504e7395d139fe4",
        "contentLength":"25476",
        "boost":0.0,
   "title":["emb - A2]
        "url":"https://www.example.com/a/b/c1/"
},
{
        "date":"1970-01-01T00:00:00Z",
        "tstamp":"2019-11-22T12:22:31.698Z",
        "digest":"e23d679991d80d832504e7395d139fe4",
        "contentLength":"25476",
        "boost":0.0,
   "title":["emb - A3]
        "url":"https://www.example.com/a/b/c2/"
}

我只是得到

{"title":"[\r\n  \"emb- A1","source":"https://www.example.com/a/b/c0/"}

而不是拥有所有响应数据。

我的代码在下面。 型号 SearchModel.cs


using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace searchEngineTesting.Models
{
    public class SearchModel
    {
        public string Title;
        public string Source;

    }
}


控制器 EngineController.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using searchEngineTesting.Models;

namespace searchEngineTesting.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class EngineController : ControllerBase {


        [HttpGet("[action]/{query}")]
        public async Task<IActionResult> Product(string query)
        {
            var model = new SearchModel();
            using (var client = new HttpClient())
            {
                try
                {
                    client.BaseAddress = new Uri("http://xx.xx.xxx.xx:8080");
                    var response = await client.GetAsync($"/abc/xxx/select?q=title%3A%22{query}%22");
                    response.EnsureSuccessStatusCode();
                    var stringResult = await response.Content.ReadAsStringAsync();
                    var root = (JObject)JsonConvert.DeserializeObject(stringResult);
                    //var details = JsonConvert.DeserializeObject<SearchModel>(stringResult);
                    var items = root.SelectToken("").Children().OfType<JProperty>().ToDictionary(p => p.Name, p => p.Value);

                    foreach (var item in items)
                    {
                        if (item.Key == "response")
                        {
                            var key = item.Value.SelectToken("").OfType<JProperty>().ToDictionary(p => p.Name, p => p.Value);

                            foreach (var k in key)
                            {
                                if(k.Key == "docs")
                                {
                                    var tests = JsonConvert.DeserializeObject<JArray>(k.Value.ToString());
                                    var data = k.Value.SelectToken("").Children().First();
                                    var test = data.SelectToken("").Children().OfType<JProperty>().ToDictionary(p => p.Name, p => p.Value).ToList();
                                    foreach (var t in test)
                                    {
                                        if (t.Key =="url")
                                        {
                                            model.Source = t.Value.ToString();
                                        }
                                        else if (t.Key == "title")
                                        {
                                            model.Title = t.Value.ToString();                                        }
                                    }
                                }
                            }
                        }
                    }

                    return new JsonResult(model);

                }
                catch (InvalidOperationException httpreq) {
                    return BadRequest("Sorry: There are no results for your query");
                }
            }
        }



    }
}

如何从实际的API中检索得到的全部响应。

请帮助..!

2 个答案:

答案 0 :(得分:0)

您的模型不是列表,而是仅一个对象,您将在循环中对其进行连续覆盖,从而仅保留一个元素。 然后,您将需要遍历所有文档,而不仅仅是使用第一个文档(例如k.Value.SelectToken("").Children().First())。

因此,您应该能够通过将模型更改为SearchModels的{​​{3}}并确保遍历所有文档来解决问题(这有助于在调试器中检查变量,以了解什么)发生)。

一种更简单的方法是使用List,您只需要使用C#类来镜像JSON的相关结构,例如:

public class Document
{
    public string Title;
    public string Url;
}

public class Result
{
    public Response response;
}

public class Response
{
    public List<Document> docs;
}

然后反序列化json简单,如下:

var result = JsonConvert.DeserializeObject<Result>(stringResult);

最后将结果转换为您的SearchModel

var searchModels = result.response.docs.Select(x => new SearchModel {Source = x.Url, Title = x.Title}).ToList();

答案 1 :(得分:0)

  

如何从实际的API中检索得到的全部响应。

如果您想返回所有实际的api响应,则只需使用以下代码:

[HttpGet("[action]/{query}")]
public async Task<IActionResult> Product(string query)
    {
        var model = new SearchModel();
        using (var client = new HttpClient())
        {
            try
            {
                client.BaseAddress = new Uri("http://xx.xx.xxx.xx:8080");
                var response = await client.GetAsync($"/abc/xxx/select?q=title%3A%22{query}%22");
                response.EnsureSuccessStatusCode();
                var stringResult = await response.Content.ReadAsStringAsync();
                var root = (JObject)JsonConvert.DeserializeObject(stringResult);

                return new JsonResult(root);
            }
            catch (InvalidOperationException httpreq)
            {

            }
        }
        return Ok()
     }

如果您只想从实际响应中返回List<SearchModel>,则不要使用var data = k.Value.SelectToken("").Children().First();,它只会检索docs数组的第一个元素。

尝试遍历k.Value.SelectToken("").Children()并返回List<SearchModel>而不是SearchModel,请参阅

[HttpGet("[action]/{query}")]
public async Task<IActionResult> Product(string query)
    {
        //initialize a list SearchModel
        var modelList = new List<SearchModel>();

        using (var client = new HttpClient())
        {
            try
            {
                client.BaseAddress = new Uri("http://xx.xx.xxx.xx:8080");
                var response = await client.GetAsync($"/abc/xxx/select?q=title%3A%22{query}%22");
                response.EnsureSuccessStatusCode();
                var stringResult = await response.Content.ReadAsStringAsync();
                var root = (JObject)JsonConvert.DeserializeObject(stringResult);

                var items = root.SelectToken("").Children().OfType<JProperty>().ToDictionary(p => p.Name, p => p.Value);

                foreach (var item in items)
                {
                    if (item.Key == "response")
                    {
                        var key = item.Value.SelectToken("").OfType<JProperty>().ToDictionary(p => p.Name, p => p.Value);

                        foreach (var k in key)
                        {
                            if (k.Key == "docs")
                            {
                                //remove .First()
                                var arrayData = k.Value.SelectToken("").Children();
                                foreach(var data in arrayData)
                                {
                                    var model = new SearchModel();
                                    var test = data.SelectToken("").Children().OfType<JProperty>().ToDictionary(p => p.Name, p => p.Value).ToList();
                                    foreach (var t in test)
                                    {
                                        if (t.Key == "url")
                                        {
                                            model.Source = t.Value.ToString();
                                        }
                                        else if (t.Key == "title")
                                        {
                                            model.Title = t.Value.ToString();
                                        }
                                    }

                                    modelList.Add(model);
                                }

                            }
                        }
                    }
                }

                return new JsonResult(modelList);

            }
            catch (InvalidOperationException httpreq)
            {

            }
        }

        return Ok();
    }