关于c#:如何检查WebClient请求中的404错误

How do I check a WebClient Request for a 404 error

我有一个正在编写的程序可以下载到文件。 第二个文件不是必需的,仅包含某些时间。 当不包含第二个文件时,它将返回HTTP 404错误。

现在的问题是,当返回此错误时,它将结束整个程序。 我想要的是继续执行该程序,并忽略HTTP错误。 因此,我的问题是如何从WebClient.DownloadFile请求中捕获HTTP 404错误?

这是当前使用的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
WebClient downloader = new WebClient();
foreach (string[] i in textList)
{
    String[] fileInfo = i;
    string videoName = fileInfo[0];
    string videoDesc = fileInfo[1];
    string videoAddress = fileInfo[2];
    string imgAddress = fileInfo[3];
    string source = fileInfo[5];
    string folder = folderBuilder(path, videoName);
    string infoFile = folder + '\\\' + removeFileType(retrieveFileName(videoAddress)) + @".txt";
    string videoPath = folder + '
\\\' + retrieveFileName(videoAddress);
    string imgPath = folder + '
\\\' + retrieveFileName(imgAddress);
    System.IO.Directory.CreateDirectory(folder);
    buildInfo(videoName, videoDesc, source, infoFile);
    textBox1.Text = textBox1.Text + @"begining download of files for" + videoName;
    downloader.DownloadFile(videoAddress, videoPath);
    textBox1.Text = textBox1.Text + @"Complete video for" + videoName;
    downloader.DownloadFile(imgAddress, imgPath);
    textBox1.Text = textBox1.Text + @"Complete img for" + videoName;
}

如果您特别想捕获错误404:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
using (var client = new WebClient())
{
  try
  {
    client.DownloadFile(url, destination);
  }
  catch (WebException wex)
  {
    if (((HttpWebResponse) wex.Response).StatusCode == HttpStatusCode.NotFound)
    {
      // error 404, do what you need to do
    }
  }
}


WebClient将为所有4xx和5xx响应抛出WebException。

1
2
3
4
5
6
try {
    downloader.DownloadFile(videoAddress, videoPath);
}
catch (WebException ex) {
    // handle it here
}

try catch放入foreach循环中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
 foreach (string[] i in textList)
 {
    try
    {
        String[] fileInfo = i;
        string videoName = fileInfo[0];
        string videoDesc = fileInfo[1];
        string videoAddress = fileInfo[2];
        string imgAddress = fileInfo[3];
        string source = fileInfo[5];
        string folder = folderBuilder(path, videoName);
        string infoFile = folder + '\\\' + removeFileType(retrieveFileName(videoAddress)) + @".txt";
        string videoPath = folder + '
\\\' + retrieveFileName(videoAddress);
        string imgPath = folder + '
\\\' + retrieveFileName(imgAddress);
        System.IO.Directory.CreateDirectory(folder);
        buildInfo(videoName, videoDesc, source, infoFile);
        textBox1.Text = textBox1.Text + @"begining download of files for" + videoName;
        if(Download(videoAddress, videoPath) == false)
        {
           //Download failed. Do what you want to do.
        }
        textBox1.Text = textBox1.Text + @"Complete video for" + videoName;
        if(Download(imgAddress, imgPath)== false)
        {
           //Download failed. Do what you want to do.
        }
        textBox1.Text = textBox1.Text + @"Complete img for" + videoName;
    }
    catch(Exception ex)
    {
        //Error like IO Exceptions, Security Errors can be handle here. You can log it if you want.
    }
 }

专用功能下载文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 private bool Download(string url, string destination)
 {
     try
     {
         WebClient downloader = new WebClient();
         downloader.DownloadFile(url, destination);
         return true;
     }
     catch(WebException webEx)
     {
        //Check (HttpWebResponse)webEx.Response).StatusCode
        // Or
        //Check for webEx.Status
     }
     return false;
 }

您可以检查WebException的状态。根据错误代码,您可以继续或中断。

阅读更多@ MSDN

  • 网络客户端
  • WebException.Status
  • WebExceptionStatus

建议

  • 使用Path.Combine创建文件夹路径。
  • 可以使用String.Format联接两个字符串,而不是+

希望这对您有用。


您可以尝试使用以下代码从WebException或OpenReadCompletedEventArgs.Error获取HTTP状态代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
HttpStatusCode GetHttpStatusCode(System.Exception err)
{
    if (err is WebException)
    {
        WebException we = (WebException)err;
        if (we.Response is HttpWebResponse)
        {
            HttpWebResponse response = (HttpWebResponse)we.Response;
            return response.StatusCode;
        }
    }
    return 0;
}

在代码中使用try catch WebException并检查Exception消息-该消息将包含http StatusCode

您可以清除Exception并继续。


重要:在404错误上,DownloadFileTaskAsync将引发异常,但也会创建一个空文件。至少可以这样混淆!

我花了很长时间才意识到除了抛出异常外,这段代码还创建了一个空文件:

1
await webClient.DownloadFileTaskAsync(new Uri("http://example.com/fake.jpg"), filename);

相反,我切换到此(DownloadDataTaskAsync而不是File):

1
2
 var data = await webClient.DownloadDataTaskAsync(new Uri("http://example.com/fake.jpg"));
 File.WriteAllBytes(filename, data);

*我不确定约有500种行为,但可以肯定的是有404种行为。


正如其他作者所写,try-catch就足够了。

另一个技巧是使用HTTP HEAD检查是否有任何东西(比执行完整的HTTP GET轻):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var url ="url to check;
var req = HttpWebRequest.Create(url);
req.Method ="
HEAD"; //this is what makes it a"HEAD" request
WebResponse res = null;
try
{
    res = req.GetResponse();
    res.Close();
    return true;
}
catch
{
    return false;
}
finally
{
    if (res != null)
        res.Close();
}

在循环内使用带有WebException的try {} catch {}块!
Dunno您正在使用什么IDE,但是通过Visual Studio,您可以获得有关该异常的很多信息:)