问题
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;
}
回答1:
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.
回答2:
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
}
}
}
回答3:
WebClient will throw a WebException for all 4xx and 5xx responses.
try {
downloader.DownloadFile(videoAddress, videoPath);
}
catch (WebException ex) {
// handle it here
}
回答4:
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
- WebClient
- WebException.Status
- WebExceptionStatus
Suggestion
- Use Path.Combine to create folder path.
- Can use String.Format to join two strings, instead of
+
.
Hope this works for you.
回答5:
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;
}
回答6:
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 :)
回答7:
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();
}
回答8:
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.
来源:https://stackoverflow.com/questions/8968641/how-do-i-check-a-webclient-request-for-a-404-error