web-dev-qa-db-fra.com

Comment vérifier une requête WebClient pour une erreur 404

J'ai un programme que j'écris qui télécharge dans des fichiers. Le second fichier n’est pas nécéssaire et n’est inclus que quelques fois. Lorsque le second fichier n'est pas inclus, une erreur HTTP 404 est renvoyée.

Maintenant, le problème est que lorsque cette erreur est renvoyée, elle met fin à tout le programme. Ce que je veux, c'est continuer le programme et ignorer l'erreur HTTP. Ma question est donc la suivante: comment puis-je intercepter une erreur HTTP 404 à partir d'une requête WebClient.DownloadFile?

C'est le code utilisé actuellement ::

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

utilisez une tentative catch webexception dans votre code. examinez le message Exception qui contiendra le code de statut http.

vous pouvez effacer l'exception et continuer.

1
Laird Streak

Si vous précisément souhaitez intercepter l'erreur 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
    }
  }
}
14
Ian Kemp

WebClient lancera une exception WebException pour toutes les réponses 4xx et 5xx.

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

Placez la trycatch dans votre boucle 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.
    }
 }

Fonction privée pour télécharger le fichier

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

Vous pouvez vérifier l'état WebException. Selon le code d'erreur, vous pouvez continuer ou interrompre.

Lire la suite @ MSDN

Suggestion

J'espère que cela fonctionne pour toi.

7
Amar Palsapure

vous pouvez essayer ce code pour obtenir le code de statut HTTP à partir de WebException ou 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;
}
1
Sergey

Important: En cas d’échec 404, DownloadFileTaskAsync lève une exception, mais crée également un fichier vide. Cela peut être déroutant pour le moins!

Cela m'a pris trop de temps pour réaliser que ce code crée un fichier vide en plus de lancer une exception:

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

Au lieu de cela, je suis passé à ceci (DownloadDataTaskAsync au lieu de File): 

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

* Je ne suis pas sûr de 500 comportements, mais à coup sûr, un 404 le fait.

0
Simon_Weaver

Utilisez un bloc try {} catch {} avec l’exception WebException dans votre boucle! Ne savez pas ce que IDE vous utilisez, mais avec Visual Studio, vous pouvez obtenir beaucoup d’informations sur l’exception :)

0
Guillaume Slashy

Comme d'autres écrivent, comme try-catch suffirait.

Une autre astuce consiste à utiliser HTTP HEAD pour vérifier s’il ya quelque chose (cela est plus léger que de faire un HTTP GET complet):

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