【问题标题】:Why can my WebClient not read a failed API call?为什么我的 WebClient 无法读取失败的 API 调用?
【发布时间】:2020-08-28 14:03:32
【问题描述】:

我的代码(用于使用 API 调用搜索 Steam 市场商品)应该将 API 调用的响应读取到我的程序中,这很好用,但是,当 API 调用失败时,我想显示一个单独的错误让用户知道出现问题的消息,但目前它只会使代码崩溃。

一个成功的 API 调用示例如下:

https://steamcommunity.com/market/priceoverview/?currency=2&appid=730&market_hash_name=Glock-18%20%7C%20Steel%20Disruption%20%28Minimal%20Wear%29

这会导致以下结果;

{"success":true,"lowest_price":"\u00a31.39","volume":"22","median_price":"\u00a31.40"}

到目前为止,这工作得很好,当使用不正确的链接时会出现问题,如下所示:

https://steamcommunity.com/market/priceoverview/?currency=2&appid=730&market_hash_name=this-skin-does-not-exist

这会导致这样的错误;

{"success":false}

我想知道什么时候发生这种情况,以便我可以向用户显示一条消息,但是在我的代码的当前状态下,当它返回时它只会崩溃。这是我当前的代码:

webpage = "https://steamcommunity.com/market/priceoverview/?currency=2&appid=730&market_hash_name=" + Model.category + Model.weapon + " | " + Model.skin + " (" + Model.wear + ")";

System.Net.WebClient wc = new System.Net.WebClient();
byte[] raw = wc.DownloadData(webpage);
string webData = System.Text.Encoding.UTF8.GetString(raw);

if (webData.Substring(11, 1) == "t")
{
    int lowestPos = webData.IndexOf("\"lowest_price\":\"");
    int volumePos = webData.IndexOf("\",\"volume\":\"");
    int medianPos = webData.IndexOf("\",\"median_price\":\"");
    int endPos = webData.IndexOf("\"}");

    Model.lowestPrice = webData.Substring(lowestPos + 16, volumePos - lowestPos - 16);
    if (Model.lowestPrice.IndexOf("\\u00a3") != -1)
    {
        Model.lowestPrice = "£" + Model.lowestPrice.Substring(6);
    }

    Model.medianPrice = webData.Substring(medianPos + 18, endPos - medianPos - 18);
    if (Model.medianPrice.IndexOf("\\u00a3") != -1)
    {
        Model.medianPrice = "£" + Model.medianPrice.Substring(6);
    }

    Model.volume = webData.Substring(volumePos + 12, medianPos - volumePos - 12);
}
else
{
    Console.WriteLine("An error has occurred, please enter a correct skin");
}

错误发生在byte[] raw = wc.DownloadData(webpage);

任何帮助将不胜感激:)

【问题讨论】:

  • 它是如何“崩溃”的?什么是“错误”?
  • 因为自 2012 年以来 WebClient 已过时并被 HttpClient 取代。这是原因之一 - 它会总是在返回不成功状态码时抛出异常,甚至一个 3xx。它也不是线程安全的
  • 根本不要使用 WebClient。请改用 HttpClient。单个 HttpClient 实例也可以被多个线程重用。使用例如HttpClient.GetAsync 检索响应并检查其StatusCode 属性like the example in the docs
  • WebClient 是为 2002 年的桌面应用程序而构建的,在 HTTP API 和 REST 之前。它的方法适用于下载页面和文件并发布到表单。这就是为什么它们被称为DownloadString 或DownloadData 等,以及为什么有些动词根本就不见了。这就是异步操作也使用事件的原因——它们被构建为调用 Winforms 事件处理程序

标签: c# webclient


【解决方案1】:

Webclient 已弃用,如果可能,您应该考虑使用 HttpClient。 Webclient 抛出异常。因此,您应该将代码包装在 try/catch 块中以捕获异常并做出相应反应:

try
{
  System.Net.WebClient wc = new System.Net.WebClient();
  byte[] raw = wc.DownloadData(webpage);
  string webData = System.Text.Encoding.UTF8.GetString(raw);
}
catch(System.Net.WebException e)
{
  //handle the error here
}

【讨论】:

    猜你喜欢
    • 2018-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多