.NET throws WebException instead of setting StatusCode - c#

I have the following code in my method:
// make the FTP request
var request = (FtpWebRequest)WebRequest.Create(serverUri);
request.KeepAlive = true;
request.Method = WebRequestMethods.Ftp.MakeDirectory;
return (FtpWebResponse)request.GetResponse();
The serverUri is valid and this works if the directory does not exist already on the server. However, if the directory does already exist a System.Net.WebException : The remote server returned an error: (550) File unavailable (e.g., file not found, no access) occurs.
Why does this exception occur when I call request.GetResponse() instead of setting the FtpWebResponse object's StatusCode to FtpStatusCode.ActionNotTakenFileUnavailable which is 550?
I find information on how to handle the exception and get the status code and description from it. But I would like to know why the exception is thrown in the first place instead of setting the response object's status code and letting the coder decide if it warrants an exception.

Because getting an error code after making an Http request matches perfectly with the Exception semantics of the language. You don't actually have a meaningful response to get back and since it is an "exceptional" case it makes sense to translate the web error to a WebException.

This is actually behaving as designed. You'll need to catch that specific exception and then interrogate the response. Per the MSDN documentation:
If a WebException is thrown, use the Response and Status properties of the exception to determine the response from the server.
So, the code might look like this:
try
{
return (FtpWebResponse)request.GetResponse();
}
catch (WebException we)
{
// interrogate the WebException for the response data you're looking for
}

Related

C# - Check if a URI that is within the network is valid

I found this code from here it works for uri like "https://google.com" but it doesn't work for something like "https://172.61.58.168/Account/Login/". I actually don't know why. I have an App using that URI that has an API that I need to call. I can successfully do an api-call and I just decided to make a validation first if the base uri exist and is valid.
Help. Thanks.
code:
bool isHttpValid = false;
try
{
//Creating the HttpWebRequest
HttpWebRequest request = WebRequest.Create("https://172.16.85.186/Account/Login/") as HttpWebRequest;
//Setting the Request method HEAD, you can also use GET too.
request.Method = "HEAD";
//Getting the Web Response.
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
//Returns TRUE if the Status code == 200
response.Close();
isHttpValid = true;
}
catch
{
//Any exception will returns false.
isHttpValid = false;
}
First of all you should use HttpClient instead of WebRequest, then you are checking that a HTTP request is valid, however your using a HTTPS URL.
If you want a method that check both HTTP and HTTPS URLs, you have to think how are you going to manage HTTPS certificates, due to that exception:
System.Net.WebException: The SSL connection could not be established, see inner exception. The remote certificate is invalid according to the validation procedure. ---> System.Net.Http.HttpRequestException: The SSL connection could not be established, see inner exception. ---> System.Security.Authentication.AuthenticationException: The remote certificate is invalid according to the validation procedure.
Maybe you want to add that custom certificate as secure, or you want to remove the security policy that checks the SSL certificates (I don't recommend it), following that other question.
I hope this can help you.

HttpWebRequest WebException ProtocolError

I'm trying to understand something about exception handling with a HttpWebRequest.
I have a client library and it's making a request to a WebAPI controller;
HttpWebRequest r = (HttpWebRequest)WebRequest.Create(url);
r.Method = "POST";
r.ContentType = "application/json";
foreach (var header in request.Headers)
{
r.Headers.Add(header.Key, header.Value.ToString());
}
r.ContentLength = request.RequestBody.Length;
using (StreamWriter writer = new StreamWriter(r.GetRequestStream()))
writer.Write(request.RequestBody);
I know the request will throw an exception, and contain the message entity already exists - 1234.
When I get the response;
using (HttpWebResponse response = (HttpWebResponse)r.GetResponse())
{
if (response.StatusCode == HttpStatusCode.OK)
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
return reader.ReadToEnd();
return "Invalid";
}
I get a WebException thrown. So, the caller of the request has a try..catch in it. And I get the WebException. What I get is a protocol error, not the 500 internal server error that was thrown (using correct status codes to represent the message comes later). Now if I read the Response of the WebException, it does contain my message and the stacktrace.
Questions
Why do I not get a status code of 500 in my response, why does it throw a protocol error?
Is there a more correct way of handling the request?
I have searched around and found some people getting this issue when not using the correct headers etc. But as far as I can tell, I have added all the headers that I can and still get the same behavior.
An 500 internal server error usually means that the API received the request but threw an unhandled exception while processing it, thus the "Internal Server Error".
You may log to a database or file all your API's unhandled exceptions to help your debugging process. Good luck.

How to process http links?

As you all know there is many file host websites, is there a way to process the http link of a of file on one of those sites and retrieve a result if the file exists or if the http link even exists or not. I know that maybe some of those file host websites uses their own APIs but i want a more generic way.
Edit:
So as i understand there is no file on a server, it's just that i have to read the response and read it properly. I want to ask another thing, what about redirection, does that mean if i got the response of a link that redirects to other link, i will get the final target from the response ?
You can find out if a file exist using the exists method:
bool System.IO.File.Exists(string path)
///
in order to find out if a file exist on a remove server you can try this:
WebRequest request;
WebResponse response;
String strMSG = string.Empty;
request = WebRequest.Create(new Uri(“http://www.yoururl.com/yourfile.jpg”));
request.Method = “HEAD”;
try
{
response = request.GetResponse();
strMSG = string.Format(“{0} {1}”, response.ContentLength, response.ContentType);
}
catch (Exception ex)
{
//In case of File not Exist Server return the (404) Error
strMSG = ex.Message;
}
see this:
If I understand you correctly, you're trying to tell if a given URL has content.
Use the
WebClient
class.
Call the url, if you receive a 200, you're good to go. A 404 exception or similar probably means the link is no good.
Or, even better way to do this is to do a HEAD http request. See here for more info on that.

How can one check to see if a remote file exists using C#

How can I check a File exits in a web location in ASP.Net(in a different web application, but same web server), currently I doing like this. Is there any better way of doing this?
using (WebClient client = new WebClient())
{
try
{
Stream stream = client.OpenRead("http://localhost/images/myimage.jpg");
if (stream != null)
{
//exists
}
}
catch
{
//Not exists
}
}
Remember that you are never going to get a 100% definitive response on the existence of a file, but the way I do it would be pretty similar to yours...
bool remoteFileExists(string addressOfFile)
{
try
{
HttpWebRequest request = WebRequest.Create(addressOfFile) as HttpWebRequest;
request.Method = "HEAD";
request.CachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore);
var response = request.GetResponse() as HttpWebResponse;
return (response.StatusCode == HttpStatusCode.OK);
}
catch(WebException wex)
{
return false;
}
}
EDIT :: looking at the edit by Anton Gogolev above (How can one check to see if a remote file exists using C#) I should have cast the response to a HttpWebResponse object and checked the status code. Edited the code to reflect that
If a file is accessible via HTTP, you can issue a HTTP HEAD requrest for that particular URL using HttpWebRequest. If HttpWebResponse.StatusCode will be 200, than file is there.
EDIT: See this on why GetResponse throws stupid exceptions when it actually should not do that.
You can use Server.MapPath to get the directory and then check if file exist using IO standard methods like File.Exists
The 404 or Not Found error message is a HTTP standard response code indicating that the client was able to communicate with the server but the server could not find what was requested. A 404 error indicates that the requested resource may be available in the future.
You can use a HEAD request (HttpWebRequest.Method = "HEAD")

How can I check whether DNS error occurred after getting WebException

Is there any to make sure that DNS errors has been occurred after getting WebException in the following code?
WebRequest request = WebRequest.Create(uri);
....
WebResponse response = request.EndGetResponse(asyncResult);
String comparison might be one way. By checking the error message we can be sure. But depending on culture the message string can vary. So this may not be the best way for checking DNS error.
One of the the WebExceptionStatus values is NameResolutionFailure. This indicates DNS errors.
Instead of relying (ever!) on the response message received, I would rely on the StatusCode of the WebResponse received. An HTTP status code in the range 4xx (400-499) would be indicative of DNS issues or errors in locating the resource.

Categories

Resources