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.
Related
We are having an Web API exposed by 3rd party which we do not have any control. It looks like they are wrapping the custom error message model on throwing back 400 (Bad Request).
We get custom error message model when using Postman
{
"Message": "Site Name Exists",
"ErrorId": "<some-guid>",
"ErrorCode": 400,
"GeneratedTime": "<some-datatime>",
"RequestedUri": "origin-api-uri"
}
We tried using HttpWebResponse or WebResponse to get the response from API but it throws exception with 400 code on httpWebRequest.GetResponse(). It does not give us the expected response as we get in Postman but it says 400 (Bad Request) and with default error message, 'The remote server returned an error'.
We want to get original error message as Postman. Any thoughts?
By default, most exceptions are translated into an HTTP response with status code 500, Internal Server Error, or 400 bad Request and this is very painful situation. You need to catch WebException in catch block.
refer to: Exception Handling in ASP.NET Web API
Give it a try.
catch (WebException ex)
{
StreamReader sr = new StreamReader(ex.Response.GetResponseStream());
Console.WriteLine(sr.ReadToEnd());
}
I have the following helper method to execute and retrieve JSON out of a HttpWebRequest.
The requests in question are being made to the Instagram API (media/tag endpoint). The method should take a request and very simply return the JSON.
private static string RequestToJson(HttpWebRequest request)
{
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
using (Stream stream = response.GetResponseStream())
using (StreamReader reader = new StreamReader(stream))
{
return reader.ReadToEnd();
}
}
}
However randomly I would receive the following exception (Visual Studio highlights the ReadToEnd() as the cause):
An unhandled exception of type 'System.IO.IOException' occurred in
System.dll
Additional information: Unable to read data from the transport connection:
An existing connection was forcibly closed by the remote host.
Dozens of request are made , with the exception appearing randomly.
Does anyone know what might cause this?
Notes:
Every request is being made on a new thread.
The stream.CanRead property is set to false only when the exception occurs.
I have a few web services up and running fine on my localhost. The problem is when I try requesting a response from it, the following error comes up when debugging:
Web Exception was unhandled by user code
The remote server returned an error: (500) Internal Server Error
The piece of my code where it throws this error is at the HttpWebResponse header:
using (HttpWebResponse httpResponse = httpRequest.GetResponse() as HttpWebResponse)
{
Encoding enc = Encoding.GetEncoding(1252);
using (StreamReader responseStream = new StreamReader(httpResponse.GetResponseStream(), enc))
{
bl = responseStream.ReadToEnd();
}
}
Any tips? I'm sort of new to this...much appreciated.
The 500 error means something went wrong in the server side.
If you also wrote the web services, that's the code you have to inspect and debug.
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
}
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")