web-dev-qa-db-ja.com

WebClientリクエストで404エラーを確認する方法

ファイルにダウンロードするプログラムを書いています。 2番目のファイルは不要なものではなく、一部のファイルのみ含まれています。 2番目のファイルが含まれていない場合、HTTP 404エラーが返されます。

ここでの問題は、このエラーが返されるとプログラム全体が終了することです。私が欲しいのは、プログラムを続行し、HTTPエラーを無視することです。それで、私の質問は、HTTP 404リクエストからWebClient.DownloadFileエラーをどのようにキャッチするかです。

これは現在使用されているコードです::

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;
}
19
Alex Gatti

使う try catchWebExceptionをコードに追加し、Exceptionメッセージを確認します。メッセージにはhttp StatusCodeが含まれます。

Exceptionをクリアして続行できます。

0
Laird Streak

特にエラー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
    }
  }
}
19
Ian Kemp

WebClientはWebExceptionをスローします すべての4xxおよび5xx応答。

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

tryループ内にcatchforeachを置きます。

 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でもっと読む

提案

  • Path.Combine を使用してフォルダパスを作成します。
  • +の代わりに、 String.Format を使用して2つの文字列を結合できます。

これがうまくいくことを願っています。

7
Amar Palsapure

このコードを試して、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;
}
1
Sergey

重要: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);

*私は500の動作についてはわかりませんが、確かに404がこれを行います。

0
Simon_Weaver

ループ内でWebExceptionを使用してtry {} catch {}ブロックを使用してください! DunnoはIDE uを使用していますが、Visual Studioを使用すると、例外に関する多くの情報を取得できます:)

0

他の書き込みと同様に、try-catchで十分です。

もう1つのヒントは、 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();
}
0
Holger