如何检查 WebClient 请求是否有 404 错误

发布于 2024-12-28 21:30:51 字数 1267 浏览 2 评论 0原文

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

现在的问题是,当返回此错误时,整个程序就会结束。我想要的是继续程序并忽略 HTTP 错误。所以,我的问题是如何从 WebClient.DownloadFile 请求捕获 HTTP 404 错误?

这是当前使用的代码::

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;
}

I have a program I'm writing that downloads to files. The second file is not neccassary and is only some times included. When the second file is not included it will return an HTTP 404 error.

Now, the problem is that when this error is returned it ends the whole program. What I want is to continue the program and ignore the HTTP error. So, my question is how do I catch an HTTP 404 error from a WebClient.DownloadFile request?

This is the code currently used::

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;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

ペ泪落弦音 2025-01-04 21:30:52

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

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
    }
  }
}

或者,使用 C# 7 或更高版本:

using (var client = new WebClient())
{
  try
  {
    client.DownloadFile(url, destination);
  }
  catch (WebException ex) when
        (ex.Response is HttpWebResponse wr && wr.StatusCode == HttpStatusCode.NotFound)
  {      
    // error 404, do what you need to do
  }
}

If you specifically want to catch error 404:

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
    }
  }
}

Or, using C# 7 or later:

using (var client = new WebClient())
{
  try
  {
    client.DownloadFile(url, destination);
  }
  catch (WebException ex) when
        (ex.Response is HttpWebResponse wr && wr.StatusCode == HttpStatusCode.NotFound)
  {      
    // error 404, do what you need to do
  }
}
活雷疯 2025-01-04 21:30:52

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

try {
    downloader.DownloadFile(videoAddress, videoPath);
}
catch (WebException ex) {
    // handle it here
}

WebClient will throw a WebException for all 4xx and 5xx responses.

try {
    downloader.DownloadFile(videoAddress, videoPath);
}
catch (WebException ex) {
    // handle it here
}
栀梦 2025-01-04 21:30:52

try catch 放入 foreach 循环中。

 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.
    }
 }

下载文件的私有函数

 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

建议

希望这对你有用。

Put the try catch inside your foreach Loop.

 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.
    }
 }

Private function to Download file

 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;
 }

You can check the WebException for status. Depending upon the error code you can continue or break.

Read More @ MSDN

Suggestion

Hope this works for you.

内心旳酸楚 2025-01-04 21:30:52

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

您可以清除异常并继续。

Use a try catch WebException in your code and examine the Exception message - it will contain the http StatusCode.

You can clear the Exception and continue.

忘年祭陌 2025-01-04 21:30:52

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

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;
}

you can try this code to get HTTP status code from WebException or OpenReadCompletedEventArgs.Error:

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;
}
椵侞 2025-01-04 21:30:52

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

Use a try{} catch{} block with the WebException inside your loop !
Dunno what IDE u are using but with Visual Studio u can get a lot of information about the exception :)

烂人 2025-01-04 21:30:52

重要提示:发生 404 故障时,DownloadFileTaskAsync 将引发异常,但也会创建一个空文件。至少可以说这可能会令人困惑!

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

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

相反,我切换到了这个(DownloadDataTaskAsync而不是File):

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

*I'我不确定 500 行为,但可以肯定 404 会这样做。

Important: On a 404 failure DownloadFileTaskAsync will throw an exception but will ALSO create an empty file. This can be confusing to say the least!

Took me way too long to realize that this code creates an empty file in addition to throwing an exception:

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

Instead I switched to this (DownloadDataTaskAsync instead of File):

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

*I'm not sure about 500 behavior, but for sure a 404 does this.

撞了怀 2025-01-04 21:30:52

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

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

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();
}

As other write, as try-catch would suffice.

Another tip is to use HTTP HEAD to check if there is anything there (it's lighter than doing a full HTTP GET):

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();
}
笨笨の傻瓜 2025-01-04 21:30:52

我会像这样使用某物。

    public void Test()
    {
        try
        {
            WebClient webClient = new WebClient();
            webClient.DownloadString("");
        }
        catch (WebException webException)
        {
            if (int.TryParse(
                Regex.Match(webException.Message, @"(?<=error:\s\()\d+(?=\))", RegexOptions.Multiline).Value,
                out var result))
            {
                switch (result)
                {
                    case 404:
                        Console.WriteLine("Error 404");
                        break;
                    case 500:
                        Console.WriteLine("Error 500");
                        break;
                }
            }
        }
    }

I would use sth like this.

    public void Test()
    {
        try
        {
            WebClient webClient = new WebClient();
            webClient.DownloadString("");
        }
        catch (WebException webException)
        {
            if (int.TryParse(
                Regex.Match(webException.Message, @"(?<=error:\s\()\d+(?=\))", RegexOptions.Multiline).Value,
                out var result))
            {
                switch (result)
                {
                    case 404:
                        Console.WriteLine("Error 404");
                        break;
                    case 500:
                        Console.WriteLine("Error 500");
                        break;
                }
            }
        }
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文