HttpWebRequest.GetResponse() , does every StatusCode besides 200 throws exception? - c#

Calling GetResponse() on an httpWebRequest,
In all my testing i saw that this call throws WebException when the request fail.
My question is why is there a StatusCode property on the HttpWebResponse ?
It seems that the GetResponse() call will only return responses with status code 200 and throw otherwise.
And should i even bother looking if the StatusCode is not 200 ?
Assuming the only thing i can do with this information is throw exception myself ...

The entire 2xx range means that the operation has completed successfully. Status code 201 for instance, indicates that a new resource has been created.
See http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html for a list of all common status codes.

Related

HttpResponseMessage not returning 400 Bad Response

I have a method within a project that checks the Http response of a URL, called ValidateAcsUrl.
In the method, the Http response of the URL is checked, and returned as a string.
The URLs I am testing have responses of:
200 OK
400 Bad Request
404 Not Found
500 Internal Server Error
And in the catch exception, if the response does not work then an "Unavailable" response is returned
All of the responses work, apart from the 400 Bad Request.
An example of a working URL is shown below, in debug mode.
The 400 Bad Request response URL (using Appending/%, after a working URL) jumps from the HttpResponseMessage line into the catch exception, which returns "Unavailable".
Does HttpResponseMessage not work with a 400 Bad Request, or is there something else I have to do?

Are exceptions an exception to the rule about not modifying the Response after next()?

While trying to find the best approach to implementing a catch-all for any uncaught exceptions I found this.
But, while implementing it, I remembered where I read:
WARNING Don't modify the Response object after calling next()..., as the response may have already started sending and you
could cause invalid data to be sent.
pg. 580
Is this an issue when the middleware is acting as a global exception handler before the MVC middleware where it seems reasonable that if the exception middleware were invoked, no response could have been started?
Invoke on Middleware:
public async Task Invoke(HttpContext context)
{
try
{
await _next(context);
}
// A catch-all for uncaught exceptions...
catch (Exception exception)
{
var response = context.Response;
response.ContentType = "application/json";
response.StatusCode = (int)HttpStatusCode.InternalServerError;
await response.WriteAsync(...);
}
}
Of course, I cannot comment on the exact intention the author had in mind when writing that. But the general idea is that you shouldn’t modify a HTTP response when it has already started. This is because the response can already be sent in parts before it is completely constructed. And when you then attempt to change the request then, you will get exceptions that you cannot modify the response.
That is why when you invoke some middleware, and that middleware is expected to produce a response, then you should not modify the response; simply because it will likely fail.
If you invoke some middleware, and that middleware does not produce a response, then of course you are free to still create a response.
For exceptions in particular, middlewares usually produce the response at the very last step, e.g. MVC works with action result objects internally and only at the end those will be executed to produce an actual result on the response. So exceptions will often be triggered before a response is produced. So it is fine to modify the response if you encounter an exception.
The built-in exception handler middleware works pretty much the same btw., so that should be a sign that what you are doing is fine. You should just be aware that modifying the response could potentially fail, so you should handle that case as well, e.g. by checking the HasStarted property.

Why does HttpClient.PostAsync not throw on failure?

In an ASP.Net Core web service if an HttpClient.GetStringAsync call fails for 404 error or whatever, it throws an HttpRequestException. This is great.
If on the other hand an HttpClient.PostAsync call fails for 404, it does not throw an exception. I have to check the status code, fabricate an exception and throw it manually.
Why the discrepency, and is there a more elegant way of dealing with this?
HttpResponseMessage response = await _http.PostAsync("api/pollapi/request", new StringContent(requestInput));
if (!response.IsSuccessStatusCode)
{
throw new HttpRequestException($"Response status does not indicate success: {(int)response.StatusCode} ({response.StatusCode}).");
}
You can use HttpResponseMessage.EnsureSuccessStatusCode method that:
Throws an exception if the IsSuccessStatusCode property for the HTTP response is false.

System.AggregateException on GetStringAsync in asp.net

I am trying to call an API like this:
var client = new HttpClient();
client.DefaultRequestHeaders.Add("apiKey", Token);
**var result = await client.GetStringAsync(GetUrl($"accounts/{accountID}/menu?skip=0&limit=1"));**
var menuList = JsonConvert.DeserializeObject<List<Menu>>(result);
but getting System.AggregateException on GetStringAsync, error CS0103: The name 'InnerExceptionCount' does not exist in the current context
and Exception Message
One or more errors occurred. (Response status code does not indicate success: 404 (Not Found).)
I see that this is returned in result
Status = WaitingForActivation, Method = "{null}", Result = "{Not yet computed}
I tried to make call using postman with same url and apikey in header and I see the results.
Can you please suggest what is wrong with above code. Api key expects only an apiKey in header.
Thanks.
Anytime that an async call fails you'll get an AggregateException, what's important is the inner exception within that.
It looks like your inner exception is 404 Not Found, which means that you're not calling the correct URL.
You said it's working in postman, that's great. To find the root cause I suggest the following:
Start Fiddler
Make the call through postman, view the request in Fiddler
Make the call through your C# code, view the request in Fiddler
Comparing the Postman request against the C# request should tell you where the error is.

C# HttpWebRequest.GetResponse - how is StatusCode usage handled for a non-exception vs webexception response?

Can someone help clear up the usage of the "StatusCode" property in HttpWebResponse and WebException?
For example it seems that if:
a) there is no exception, then the HttpWebResponse will have a StatusCode that could have some values that indicate both:
- success (e.g. OK, Accepted etc)
- failure (e.g. UseProxy, RequestTimeout etc)
b) there is a WebExeption throw, which itself has a response object that again has a StatusCode (which I assume is based on the same HttpStatusCode Enumeration.
Question 1
- Is there any consistency in terms of what StatusCode's will trigger a WebException (and you'd pick up the detail within the exception), versus which would come back without an exception but you'd find out the result in the StatusCode of the response object?
Question 2 - Or more specifically what is the pseduo code (or C# code itself) for trying to handle a httpWebRequest.GetResponse call such that you want to differentiate between the categories of responses for the user:
proxy settings / proxy issue
=> so can tell user to fix proxy settings
connectivity issue / web-server down
=> so user is aware of this
server side error (e.g. server is there but there is an issue handling the request - e.g content not there)
=> so user can raise with website manager
success case (and I assume this would be more than just the OK)
=> na (success case)
thanks
In my experience the response status code only returns 200 or 0. Anything else comes through the WebException, including proxy errors like 407 or 417.
The WebException is thrown whenever the web request cannot be executed successfully. For e.g 400 and 500 series of responses.
WebExcpetion has a property named Status which will return the actual status of the response i.e 500 (Internal Server Error).
Here is the list of all response codes: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
===============================================================================
In general:
1xx series of code = provisional response. These are not error codes. For e.g the 100 Continue response which tells that client should continue with its request. Usually WebRequest will not return such response, and handle it itself by sending the rest of request.
2xx series of code = Request was successful received, understood and accepted. These are not error codes. For e.g 200 OK
3xx series of code = Further action needs to be taken. Generally this is not error code (usually its for re-direction) for e.g '301 Moved Permanently', which means that the resource being request is moved to a new location, so any further requests by the client should be on the new URL provided in the response.
OR '305 Use Proxy', which according to you results in an Exception.
4xx series of code = Client errors. These can result in exception. for e.g '400 Bad Request' or '401 Unauthorized'
5xx series of code = Server errors. These can result in exception. for e.g '500 Internal Server Error' or '504 Gateway Timeout'

Categories