问题描述
Newtonsoft.Json.JsonReaderException:“完成读取JSON内容后遇到的其他文本
你好,
我尝试从API(steam-API)提供的大数组中获取每个对象。
我需要多次调用才能获取所有对象,因为它们是“ total_count”:15228 。
这是我获取first page的方法,该方法工作得很好:
public static Task LoadAllItemsAsync()
{
int start=0;
string responseData = "";
using (WebClient w = new WebClient())
{
responseData = responseData + w.DownloadString("https://steamcommunity.com/market/search/render/?search_descriptions=0&sort_column=default&sort_dir=desc&appid=730&norender=1&count=100&start=" + start);
Thread.Sleep(3000);
w.Dispose();
}
start = start + 100;
dynamic parsedJson = JsonConvert.DeserializeObject(responseData);
string jsonData = JsonConvert.SerializeObject(parsedJson,Formatting.Indented);
System.IO.File.WriteAllText(System.IO.Path.GetFullPath(@"..\..\SteamData\SteamItems.json"),jsonData);
return Task.CompletedTask;
}
要获取所有对象,我尝试通过将起始值增加100 来遍历所有页面,并且这是我得到异常的地方我尝试反序列化 responsData 字符串。 代码:
public static Task LoadAllItemsAsync()
{
int start=0;
string responseData = "";
for(int i = 0; i <= 1; i++)
{
using (WebClient w = new WebClient())
{
responseData = responseData + w.DownloadString("https://steamcommunity.com/market/search/render/?search_descriptions=0&sort_column=default&sort_dir=desc&appid=730&norender=1&count=100&start=" + start);
Thread.Sleep(3000);
w.Dispose();
}
start = start + 100;
}
dynamic parsedJson = JsonConvert.DeserializeObject(responseData); //Newtonsoft.Json.JsonReaderException: "Additional text encountered after finished reading JSON content
string jsonData = JsonConvert.SerializeObject(parsedJson,jsonData);
return Task.CompletedTask;
}
我在Google上找到了一些东西,但我不理解,也不知道如何将其应用到我的代码中。 我非常感谢您的回答。
编辑:
我尝试过的:
public static Task LoadAllItemsAsync()
{
int start=0;
string responseData = "";
string jsonData = "";
for (int i = 0; i <= 1; i++)
{
using (WebClient w = new WebClient())
{
responseData = responseData + w.DownloadString("https://steamcommunity.com/market/search/render/?search_descriptions=0&sort_column=default&sort_dir=desc&appid=730&norender=1&count=100&start=" + start);
dynamic parsedJson = JsonConvert.DeserializeObject(responseData);
jsonData = jsonData + JsonConvert.SerializeObject(parsedJson,Formatting.Indented);
}
start = start + 100;
}
System.IO.File.WriteAllText(System.IO.Path.GetFullPath(@"..\..\SteamData\SteamItems.json"),jsonData);
return Task.CompletedTask;
}
解决方法
请检查以下代码。第一步是从您的json中提取c#类型-为此,我使用了https://json2csharp.com/。然后,您应该遍历请求,并将每个请求反序列化为对象。将所需的所有对象收集在一个单独的列表中,进行序列化并写入文件。
using Newtonsoft.Json;
using System.Collections.Generic;
using System.IO;
using System.Net.Http;
using System.Threading;
namespace SteamMarketJson
{
public class Searchdata
{
public string query { get; set; }
public bool search_descriptions { get; set; }
public int total_count { get; set; }
public int pagesize { get; set; }
public string prefix { get; set; }
public string class_prefix { get; set; }
}
public class AssetDescription
{
public int appid { get; set; }
public string classid { get; set; }
public string instanceid { get; set; }
public string background_color { get; set; }
public string icon_url { get; set; }
public int tradable { get; set; }
public string name { get; set; }
public string name_color { get; set; }
public string type { get; set; }
public string market_name { get; set; }
public string market_hash_name { get; set; }
public int commodity { get; set; }
}
public class Result
{
public string name { get; set; }
public string hash_name { get; set; }
public int sell_listings { get; set; }
public int sell_price { get; set; }
public string sell_price_text { get; set; }
public string app_icon { get; set; }
public string app_name { get; set; }
public AssetDescription asset_description { get; set; }
public string sale_price_text { get; set; }
}
public class RootObject
{
public bool success { get; set; }
public int start { get; set; }
public int pagesize { get; set; }
public int total_count { get; set; }
public Searchdata searchdata { get; set; }
public List<Result> results { get; set; }
}
class Program
{
static HttpClient httpClient = new HttpClient();
private const string BASE_URL = "https://steamcommunity.com/market/search/render/?search_descriptions=0&sort_column=default&sort_dir=desc&appid=730&norender=1&count=100&start=";
static void Main(string[] args)
{
int start = 0;
List<Result> results = new List<Result>(); // you probably want to store results only
RootObject rootObject = null;
do
{
var response = httpClient.GetAsync(BASE_URL + start).Result; // use await instead of .Result when used in methods
var body = response.Content.ReadAsStringAsync().Result;
rootObject = JsonConvert.DeserializeObject<RootObject>(body);
if (rootObject.results != null)
{
results.AddRange(rootObject.results);
}
start += 100;
Thread.Sleep(3000);
}
while (start < rootObject.total_count);
// write to file
var jsonResult = JsonConvert.SerializeObject(results);
File.WriteAllText("D:\\file.txt",jsonResult);
// read and deserialize it back
var fileContent = File.ReadAllText("D:\\file.txt");
var items = JsonConvert.DeserializeObject<List<Result>>(fileContent);
}
}
}