Checking if URL is valid without downloading the file in c# - c#

I'm trying to check is a given URL is Valid and downloadable.
I wrote this code and it does work but i'm wondering if it can be achieved without the ugly try-catch
public static bool IsUrlValid(string url)
{
try
{
WebClient webClient = new WebClient();
var stream = webClient.OpenRead(url);
return true;
}
catch (Exception ex)
{
return false;
}
}

Related

400 Bad request on c# code

Getting an error exception thrown on this small piece of code but I can't figure out why / where. Fairly new to this so any help would be apprecaited
private void GetServiceData(string url)
{
try
{
if (!string.IsNullOrEmpty(this.Service) && !string.IsNullOrEmpty(url))
{
string data = string.Empty;
string name = string.Format("{0}Data", this.Service);
using (WebClient client = new WebClient())
{
data = client.DownloadString(url);
}
Page.ClientScript.RegisterHiddenField(name, data);
}
}
catch (Exception ex)
{
Shared.Utilities.ExceptionLog.WriteExceptionToLog(ex, "CourseFinderServiceControl.GetServiceData()");
}
}
If this is for Twitch, you need to specify client when requesting the data.

Download vimeo video through its URL

I am trying to achieve this for vimeo videos through C# code, but the file being downloaded is the HTML. Can someone tell me how to do this? Below you can find the two handlers I implemented. Both have the same behaviour that I already described.
Handle.GET("/testDownload", (Request r) =>
{
Response response = 0;
try
{
WebClient webClient = new WebClient();
webClient.DownloadFile("https://player.vimeo.com/video/140308351", #"c:\binte\test");
}
catch (Exception ex)
{
GlobalDictionary.errorLog.LogError("Error in test download handler : " + ex.Message);
}
response.Body = "success";
return response;
}, new HandlerOptions() { SkipMiddlewareFilters = true });
Handle.GET("testDownloadVideo?url={?}", (string url, Request r) =>
{
Response response = 0;
string fileName = "testDownload.mpeg";
try
{
using (WebClient myWebClient = new WebClient())
{
myWebClient.DownloadFileAsync(new Uri(url), fileName);
}
}
catch (Exception ex)
{
GlobalDictionary.errorLog.LogError("Error in test download handler : " + ex.Message);
}
response.Body = "success";
return response;
}, new HandlerOptions() { SkipMiddlewareFilters = true });
EDIT: After some research, I think this is not possible to be done, unless I would be the owner of the video, and therefore able to use the API for that purpose. I will leave the question open though, one day this might change.

Uri.IsWellFormedUriString returns true, but cannot read from a url

I am trying to check if the url http://master.dev.brandgear.net is valid by the following method:
private bool UrlIsValid(string url)
{
using (var webClient = new WebClient())
{
bool response;
try
{
webClient.UseDefaultCredentials = true;
using (Stream strm = webClient.OpenRead(url))
{
response = true;
}
}
catch (WebException we)
{
response = false;
}
return response;
}
}
However, I am getting a web exception "404 not found.". I have checked the uri with Uri.IsWellFormedUriString and it is returning true. However, the same url can be opened through a browser. Any idea how to validate it?
I ran your example with following URL http://master.dev.brandgear.net and exception is also raised. If you open same URL in browser (for example Firefox) and run Firebug plugin, open Network tab you will see error 404 (Page not found). Your code is OK, but server returns 404.
To really get a response, you have to use WebException instead of GetResponse or GetResponseStream methods when the 404 exception happens.Also use HttpWebRequest and HttpWebResponse in these situations for better control,so after the exception occurs you check its state to see if its a ProtocolError and if so get the response from there:
private bool UrlIsValid(string url)
{
bool response = false;
HttpWebResponse rep = null;
try
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
rep = (HttpWebResponse)request.GetResponse();
}
catch (WebException we)
{
if (we.Status == WebExceptionStatus.ProtocolError)
rep = (HttpWebResponse)we.Response;
}
if (rep != null)
{
try
{
using (Stream strm = rep.GetResponseStream())
{
response = true;
}
}
catch (WebException ex)
{
//no need variable is already false if we didnt succeed.
//response = false;
}
}
return response;
}

HttpWebRequest proper exception handling

So I'm using the HttpWebRequest API in the System.Net assembly but because C# has no checked exceptions, I'm not sure where to put my try-catch blocks to properly handle inevitable exceptions caused by common things like a network error. You know, in Java we would call these plain old checked IOExceptions.
This is what I have so far. Are my try-catch blocks properly set up to handle network errors? Am I wrapping the right method calls? Looking at the documentation, I think they are right, but I need a second pair of eyes.
HttpWebRequest request = WebRequest.CreateHttp(url);
request.Method = "POST";
request.BeginGetRequestStream(getRequestResult =>
{
HttpWebRequest getRequestRequest = (HttpWebRequest) getRequestResult.AsyncState;
try
{
Stream requestStream = getRequestRequest.EndGetRequestStream(getRequestResult);
requestStream.Write(parametersData, 0, parametersData.Length);
requestStream.Dispose();
getRequestRequest.BeginGetResponse(getResponseResult =>
{
HttpWebRequest getResponseRequest = (HttpWebRequest)getResponseResult.AsyncState;
try
{
WebResponse response = getResponseRequest.EndGetResponse(getRequestResult);
Stream responseStream = response.GetResponseStream();
StreamReader reader = new StreamReader(responseStream);
string jsonString = reader.ReadToEnd();
reader.Dispose();
JObject jsonObject = JObject.Parse(jsonString);
onResult(StatusCode.Ok, jsonObject);
}
catch (WebException)
{
onResult(StatusCode.NetworkError);
}
}, getRequestRequest);
}
catch (IOException)
{
onResult(StatusCode.NetworkError);
}
}, request);
First off, unless there's some reason that you need to use HttpWebRequest, then you're better off using WebClient.UploadString instead, or any of WebClient's other UploadXXX overloads for uploading name/value pairs, files, binary data, etc. This will be much easier for you, and easier to troubleshoot and debug. Also, another problem is that you're treating exceptions during JSON parsing or during your onResult handler error as network errors.
Below are three examples of using WebClient that you might want to try: a synchronous version, an "old-style" async version, and a "new-style" async version that uses async/await. All three versions also try to fix the exception handling issue that I noted above. If you don't need async support, then the first version will be easiest.
static void PostSync (string url, string parametersData)
{
using (WebClient wc = new WebClient())
{
wc.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded"; // or "application/json" or ...
try
{
string htmlResult = wc.UploadString(url, parametersData); // or UploadValues, UploadFile, ...
JObject jsonObject = null;
try
{
jsonObject = JObject.Parse(htmlResult);
}
catch (JsonException ex)
{
onResult(StatusCode.JsonError);
}
onResult(StatusCode.Ok, jsonObject);
}
catch (System.Net.WebException ex)
{
onResult(StatusCode.NetworkError);
}
}
}
static void PostAsync(string url, string parametersData)
{
using (WebClient wc = new WebClient())
{
wc.UploadStringCompleted += (Object sender, UploadStringCompletedEventArgs e) =>
{
if (e.Error != null)
onResult(StatusCode.NetworkError);
JObject jsonObject = null;
try
{
jsonObject = JObject.Parse(e.Result);
}
catch (JsonException ex)
{
onResult(StatusCode.JsonError);
}
onResult(StatusCode.Ok, jsonObject);
};
try
{
wc.UploadStringAsync(new Uri(url, UriKind.Absolute), parametersData);
}
catch (System.Net.WebException ex)
{
onResult(StatusCode.NetworkError);
}
}
}
static async void PostTaskAsync(string url, string parametersData)
{
using (WebClient wc = new WebClient())
{
wc.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded"; // or "application/json" or ...
try
{
string htmlResult = await wc.UploadStringTaskAsync(url, parametersData); // or UploadValues, UploadFile, ...
JObject jsonObject = null;
try
{
jsonObject = JObject.Parse(htmlResult);
}
catch (JsonException ex)
{
onResult(StatusCode.JsonError);
}
onResult(StatusCode.Ok, jsonObject);
}
catch (System.Net.WebException ex)
{
onResult(StatusCode.NetworkError);
}
}
}

Exception handling the right way for WebClient.DownloadString

I was wondering what exceptions I should protect myself against when using WebClient.DownloadString.
Here's how I'm currently using it, but I'm sure you guys can suggest better more robust exception handling.
For example, off the top of my head:
No internet connection.
Server returned a 404.
Server timed out.
What is the preferred way to handle these cases and throw the exception to the UI?
public IEnumerable<Game> FindUpcomingGamesByPlatform(string platform)
{
string html;
using (WebClient client = new WebClient())
{
try
{
html = client.DownloadString(GetPlatformUrl(platform));
}
catch (WebException e)
{
//How do I capture this from the UI to show the error in a message box?
throw e;
}
}
string relevantHtml = "<tr>" + GetHtmlFromThisYear(html);
string[] separator = new string[] { "<tr>" };
string[] individualGamesHtml = relevantHtml.Split(separator, StringSplitOptions.None);
return ParseGames(individualGamesHtml);
}
If you catch WebException, it should handle most cases. WebClient and HttpWebRequest throw a WebException for all HTTP protocol errors (4xx and 5xx), and also for network level errors (disconnection, host not reachable, etc)
How do I capture this from the UI to show the error in a message box?
I'm not sure I understand your question... Can't you just show the exception message?
MessageBox.Show(e.Message);
Don't catch the exception in FindUpcomingGamesByPlatform, let it bubble up to the calling method, catch it there and show the message...
I usually handle it like this to print any exception message the remote server is returning. Given that the users are allowed to see that value.
try
{
getResult = client.DownloadString(address);
}
catch (WebException ex)
{
String responseFromServer = ex.Message.ToString() + " ";
if (ex.Response != null)
{
using (WebResponse response = ex.Response)
{
Stream dataRs = response.GetResponseStream();
using (StreamReader reader = new StreamReader(dataRs))
{
responseFromServer += reader.ReadToEnd();
}
}
}
_log.Error("Server Response: " + responseFromServer);
MessageBox.Show(responseFromServer);
}
I use this code:
Here I init the webclient whithin the loaded event
private void LayoutRoot_Loaded(object sender, RoutedEventArgs e)
{
// download from web async
var client = new WebClient();
client.DownloadStringCompleted += client_DownloadStringCompleted;
client.DownloadStringAsync(new Uri("http://whateveraurisingis.com"));
}
The callback
void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
#region handle download error
string download = null;
try
{
download = e.Result;
}
catch (Exception ex)
{
MessageBox.Show(AppMessages.CONNECTION_ERROR_TEXT, AppMessages.CONNECTION_ERROR, MessageBoxButton.OK);
}
// check if download was successful
if (download == null)
{
return;
}
#endregion
// in my example I parse a xml-documend downloaded above
// parse downloaded xml-document
var dataDoc = XDocument.Load(new StringReader(download));
//... your code
}
Thanks.
According to the MSDN documentation, the only non-programmer exception is WebException, which can be raised if:
The URI formed by combining BaseAddress and address is invalid.
-or-
An error occurred while downloading the resource.

Categories

Resources