.Net 解析器 JSON 来自打开 API

.Net Parser JSON from a open API

我正在做一个小项目来处理游戏中的一些大数据,这将使我能够查看一些高级分析,但是,我遇到了困难.... 以下 URL (Click Here) 是一个开放的 API,returns 一个 JSON 结果,我正在尝试将其作为我自己的数据进行处理。

我已经制作了一个 class 应该将这些数据处理到我的模型中,但是,每次调用第 5 行时 client.DownloadString 我都会收到错误 403,有什么办法可以解决这个问题吗? 我不认识 api 的所有者。

public IActionResult Index(object sender, EventArgs e)
{
    var model = new FresnoVm();
    WebClient client = new WebClient();
    string strPageCode = client.DownloadString("https://api.upx.world/bigdata/query?neighborhood=210&neighborhood=359&neighborhood=367&neighborhood=366&neighborhood=356&neighborhood=364&city=0&status=All&mintMin=0&mintMax=100000000&saleMin=0&saleMax=100000000&skip=0&fsa=All&sort=mint_price&ascOrDesc=1");
    dynamic dobj = JsonConvert.DeserializeObject<dynamic>(strPageCode);

    price = dobj["data"]["properties"]["sale_price_upx"].ToString();

    model.test = price;

    return View("~/Features/Fresno/Index.cshtml", model);
}

添加如下简单的行

wb.Headers.Add("User-Agent: Other");   //that is the simple line!

同时按照 this answer by Borg8 to WebClient 403 Forbidden is sufficient to download the response string, since the returned string is roughly 1.6MB it would be better to deserialize directly from the response stream, as recommended in Newtonsoft's Performance Tips: Optimize Memory Usage 中的建议将 "User-Agent: Other" 添加到 wb.Headers

首先,定义如下辅助方法:

public static class JsonExtensions
{
    public static T GetFromJson<T>(string url, JsonSerializerSettings settings = default)
    {
        var request = (HttpWebRequest)HttpWebRequest.Create(url);
        // User-Agent as suggested by this answer 
        // by https://whosebug.com/users/873595/borg8
        // To 
        request.UserAgent = "Other";

        using (var response = (HttpWebResponse)request.GetResponse())
        {
            if (response.StatusCode == HttpStatusCode.OK)
            {
                using (var stream = response.GetResponseStream())
                using (var textReader = new StreamReader(stream))
                {
                    settings = settings ?? new JsonSerializerSettings { CheckAdditionalContent = true };
                    return (T)JsonSerializer.CreateDefault(settings).Deserialize(textReader, typeof(T));
                }
            }
            else
            {
                throw new ApplicationException(); // Throw some exception with a message of your choice
            }
        }
    }
}

然后你可以做:

var dobj = JsonExtensions.GetFromJson<JToken>(url);
var prices = dobj["data"]["properties"].Select(t => (decimal?)t["last_paid_price_upx"]).ToList(); // Or cast to (string) if you prefer

备注:

  • 返回的 JSON 中没有名为 "sale_price_upx" 的 属性。一些(但不是全部)data.properties[*] 对象包含 "last_paid_price_upx" 属性,因此上面的代码显示了一个示例,说明如何将这些对象提取为可为 null 的小数。

  • LINQ-to-JSON 文档对象模型可以为 属性 名称使用大量内存。将大量数据反序列化为直接包含您需要的属性的显式数据模型可能会获得更好的性能。

演示 fiddle here.