我需要从URL获取数据。
下面的代码给出了“读取文件末尾”的错误。然而,URL是正确的,可以粘贴到浏览器中并查看结果。几次我得到了“超出时间限制”的错误,不确定我能做些什么。
问题是数据可能在几个页面上。我是否必须从page1中选择total_pages并进行循环?有更好的解决方案吗?
以下是代码:
string url="https://jsonmock.hackerrank.com/api/movies/search/?Title=spiderman&page=1";
string res=MakeRequest(url);
makeRequest的:
static public string MakeRequest(string url)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.ContentType = "application/json; charset=utf-8";
request.PreAuthenticate = true;
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
using (Stream responseStream = response.GetResponseStream())
{
StreamReader reader = new StreamReader(responseStream, Encoding.UTF8);
return (reader.ReadToEnd());
}
}
以下是数据(第2页)的内容
{"page":"2","per_page":10,"total":13,"total_pages":2,"data":[{"Poster":"N/A","Title":"They Call Me Spiderman","Type":"movie","Year":2016,"imdbID":"tt5861236"},{"Poster":"N/A","Title":"The Death of Spiderman","Type":"movie","Year":2015,"imdbID":"tt5921428"},{"Poster":"https://images-na.ssl-images-amazon.com/images/M/MV5BZDlmMGQwYmItNTNmOS00OTNkLTkxNTYtNDM3ZWVlMWUyZDIzXkEyXkFqcGdeQXVyMTA5Mzk5Mw@@._V1_SX300.jpg","Title":"Spiderman in Cannes","Type":"movie","Year":2016,"imdbID":"tt5978586"}]}
答案 0 :(得分:4)
使用HttpClient和Newtonsoft.Json完成示例。
首先,让我们定义数据传输对象的类,以匹配API中的json对应项:
public class PageResponse
{
public string Page { get; set;}
[JsonProperty("per_page")]
public int PerPage { get; set;}
public int Total { get; set; }
[JsonProperty("total_pages")]
public int TotalPages { get; set; }
public IEnumerable<Movie> Data { get; set; }
}
public class Movie
{
public string Poster { get; set; }
public string Title { get; set; }
public string Type { get; set; }
public int Year { get; set; }
[JsonProperty("imdbID")]
public string ImdbId { get; set; }
}
然后让我们创建一个API调用方法,该方法使用do-while循环并执行请求,直到我们检索所有页面或失败(由于某种原因):
public static async Task<IEnumerable<Movie>> GetMoviesAsync()
{
var movies = new List<Movie>();
var url = "http://jsonmock.hackerrank.com/api/movies/search/?Title=spiderman";
int currentPage = 1;
int totalPages = 0;
var nextUrl = $"{url}&page={currentPage}";
using (var httpClient = new HttpClient())
{
do
{
HttpResponseMessage response = await httpClient.GetAsync(nextUrl);
if (response.IsSuccessStatusCode)
{
string json = await response.Content.ReadAsStringAsync();
var pageResponse = JsonConvert.DeserializeObject<PageResponse>(json);
if (pageResponse != null && pageResponse.Data.Any())
{
movies.AddRange(pageResponse.Data);
totalPages = pageResponse.TotalPages;
currentPage++;
nextUrl = $"{url}&page={currentPage}";
}
else
{
break; // or throw exception
}
}
else
{
break; // or throw exception
}
} while (currentPage < totalPages);
}
return movies;
}
最后从Main方法调用GetMoviesAsync:
static void Main(string[] args)
{
IEnumerable<Movie> movies = GetMoviesAsync().GetAwaiter().GetResult();
Console.WriteLine($"Retrieved {movies.Count()} movies.");
}
...在编辑时,这将共检索13部电影:
Retrieved 13 movies.
另外作为旁注,最佳做法是访问修饰符,例如 public 始终在 static 关键字之前编写。即。
public static ...
不
static public ...
编辑:根据以下评论中的建议更新更多详情
EDIT2:通过省略ContinueWith调用来改进GetMoviesAsync()