Asp.net HttpWebResponse - how can I not depend on WebException for flow control? - asp.net

I need to check whether the request will return a 500 Server Internal Error or not (so getting the error is expected). I'm doing this:
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
request.Method = "GET";
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
if (response.StatusCode == HttpStatusCode.OK)
return true;
else
return false;
But when I get the 500 Internal Server Error, a WebException is thrown, and I don't want to depend on it to control the application flow - how can this be done?

I think this MSDN articles will help you:
http://msdn.microsoft.com/en-us/library/system.net.webexception.status.aspx

Indeed, given the example at msdn, there is no way to not depend on the exception for control flow. Here's the example they give:
try {
// Create a web request for an invalid site. Substitute the "invalid site" strong in the Create call with a invalid name.
HttpWebRequest myHttpWebRequest = (HttpWebRequest) WebRequest.Create("invalid site");
// Get the associated response for the above request.
HttpWebResponse myHttpWebResponse = (HttpWebResponse) myHttpWebRequest.GetResponse();
myHttpWebResponse.Close();
}
catch(WebException e) {
Console.WriteLine("This program is expected to throw WebException on successful run."+
"\n\nException Message :" + e.Message);
if(e.Status == WebExceptionStatus.ProtocolError) {
Console.WriteLine("Status Code : {0}", ((HttpWebResponse)e.Response).StatusCode);
Console.WriteLine("Status Description : {0}", ((HttpWebResponse)e.Response).StatusDescription);
}
}
catch(Exception e) {
Console.WriteLine(e.Message);
}
Apparently, sometimes you do have to go down that route. Ah, well.

Related

How to send success and error messages to jQuery AJAX call from a webmethod

I am calling an asp.net webform's webmethod using jQuery AJAX, from an aspx page. When the webmethod experiences an exception I am throwing an HttpResponseException exception. I am not sure what's the best way to return a success message. In a Web API, I would have returned a ApiController.Created(HttpStatusCode) or Ok(200). But I don't see such an option available on a webmethod. In the AJAX call I have to handle success and error accordingly. The following is my code:
[WebMethod()]
public async Task<IHttpActionResult> ProcessData(CustomerData customerData)
{
try
{
HttpClient client = new HttpClient();
HttpResponseMessage resp = await client.PostAsync(<data>);
if (resp.IsSuccessStatusCode)
{
string result = await resp.Content.ReadAsStringAsync();
return ???;//how to send success message?
}
else
{
string reasonAndStatusCode = resp.StatusCode + "; " + resp.ReasonPhrase;
string errorMessage = "Method Name: ProcessData." +
"Did not process customer data." +
"Status Code and Reason: " +
reasonAndStatusCode;
HttpResponseMessage error = GenerateError(resp.StatusCode, errorMessage.ToString());
throw new HttpResponseException(error);
}
}
catch (Exception ex)
{
HttpResponseMessage error = GenerateError(HttpStatusCode.InternalServerError,
errorMessage.ToString());
throw new HttpResponseException(error);
}
}
You can change the response status code using HttpContext Current static object.
For example, if you want to send a 404 status code, see the code below.
HttpContext.Current.Response.StatusCode = (int)HttpStatusCode.NotFound;

Asp.net web method ajax call show stack trace and actual exception while custom errors mode on

I am calling web method using ajax call.Here is the example call.
[WebMethod(true)]
public static string Save(string customParams)
{
throw new ApplicationException("Example Exception");
}
$.ajax({
url: url,
type: "POST",
data: data,
contentType:"application/json; charset=utf-8",
dataType: props.dataType ? props.dataType : "text",
error: function (xhr, errorType, ex) {
debugger;
err(ex);
}
})
If that method throws an exception I only get 500 internal server error.Stacktrace is empty and I can't get the inner exception message.I decorated webmethod with try catch blocks and return HttpException and set text of it but it didn't work.
try
{
throw new ApplicationException("Example Exception");
}
catch (Exception e)
{
throw new HttpException(500,e.Message,e);
}
I also tried this solution again with no luck.
catch (Exception e)
{
HttpContext.Current.Response.Write(e.Message.ToJsonString());
HttpContext.Current.Response.StatusCode=500;
}
By the way I also experimented that uncaught exception when request is ajax request can't be caught by Global.asax's Application_Error.Here is the issue.
I switched custom error off.Now it's displaying error but still not a intented solution.
Any solution ? Thanks in advance.
I found some way of achieving this.As you may notice I am changing 500 error responseText with the actual exception's message and stacktrace.
First Clear Response and Header.Then set TrySkipIisCustomErrors = true in order to not let asp.net to return 500 error page.After that write actual error message to the response,flush it and end processing page.I really don't know this is ideal way of doing but so far I only got this solution.
Here is the code.
public static string ProcessAjaxException(Exception ex)
{
if (!HttpContext.Current.Request.IsAjaxRequest())
{
return null;
}
var page = (Page)HttpContext.Current.CurrentHandler;
string url = page.AppRelativeVirtualPath;
Framework.Core.Logging.LoggerFactory.Error(url, ex);
var jsonExceptionDetails = new { ex.Message, ex.StackTrace, statusText = "500" };
var serializedExcpDetails = JsonConvert.SerializeObject(jsonExceptionDetails);
//Erases any buffered HTML output.
HttpContext.Current.Response.Clear();
//Erases header
HttpContext.Current.Response.ClearHeaders();
/*If the IHttpResponse::SetStatus method was called by using the fTrySkipCustomErrors flag,
* the existing response is passed through,
* and no detailed or custom error is shown.*/
HttpContext.Current.Response.TrySkipIisCustomErrors = true;
HttpContext.Current.Response.ContentType = "application/json; charset=utf-8";
HttpContext.Current.Response.StatusCode = 500;
//Send all buffered output to client
HttpContext.Current.Response.Flush();
HttpContext.Current.Response.Write(serializedExcpDetails);
//Stop processing the page
HttpContext.Current.Response.End();
return null;
}

WebException timeout vs HttpWebResponse timeout?

I'm using the Asp.Net WebClient to create an HTTP post.
The below code has try-catch block around the code which catches WebException:
try
{
using (MyWebClient wc = new MyWebClient())
{
wc.Headers[HttpRequestHeader.ContentType] = _lender.ContentType;
wc.Timeout = 200;
return _lender.GetResult(wc.UploadString(_lender.PostUri, _lender.PostValues));
}
}
catch (WebException ex)
{
return new ServiceError(ex.Status.ToString());
}
The main exceptions I'm looking for are timeouts. I've extended WebClient to allow me to set the timeout.
When I set the timeout to say 100ms, an exception is thrown as expected. I can get the WebException status as per the example (it returns "timeout"), however, I want to return status codes too.
If I extract the httpwebresponse using ex.Response I get a null value returned, when I was expecting an associated status code.
Why do I not get an HttpStatus.Request.Timeout?
I have the same problem and I realise a few things while I search for a solution.
WebExceptionStatus enum is not equivalent to http status code that the API you call returned. Instead it is a enum of possible error that may occour during a http call.
The WebExceptionStatus error code that will be returned when you receive an error (400 to 599) from your API is WebExceptionStatus.ProtocolError aka number 7 as int.
When you need to get the response body or the real http status code returned from the api, first you need to check if WebException.Status is WebExceptionStatus.ProtocolError. Then you can get the real response from WebExceptionStatus.Response and read its content.
Sometimes the timeout is handled by the caller (aka your code) so you do not have a response in that case. So you can look if WebException.Status is WebExceptionStatus.Timeout
This is an example:
try
{
...
}
catch (WebException webException)
{
if (webException.Status == WebExceptionStatus.ProtocolError)
{
var httpResponse = (HttpWebResponse)webException.Response;
var responseText = "";
using (var content = new StreamReader(httpResponse.GetResponseStream()))
{
responseText = content.ReadToEnd(); // Get response body as text
}
int statusCode = (int)httpResponse.StatusCode; // Get the status code
}
else if (webException.Status == WebExceptionStatus.ProtocolError)
{
// Timeout handled by your code. You do not have a response here.
}
// Handle other webException.Status errors. You do not have a response here.
}

check URL exists or throws page not found message in asp.net

I want to validate an url, whether it exists or throwing page not found error. can anyone help me how to do it in asp.net.
for e.g., my url may be like http://www.stackoverflow.com or www.google.com i.e., it may contain http:// or may not. when i check, it should return the webpage valid if exists or page not found if doesnot exists
i tried HttpWebRequest method but it needs "http://" in the url.
thanks in advance.
protected bool CheckUrlExists(string url)
{
// If the url does not contain Http. Add it.
if (!url.Contains("http://"))
{
url = "http://" + url;
}
try
{
var request = WebRequest.Create(url) as HttpWebRequest;
request.Method = "HEAD";
using (var response = (HttpWebResponse)request.GetResponse())
{
return response.StatusCode == HttpStatusCode.OK;
}
}
catch
{
return false;
}
}
Try this
using System.Net;
////// Checks the file exists or not.
bool FileExists(string url)
{
try
{
//Creating the HttpWebRequest
HttpWebRequest request = WebRequest.Create(url) 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 TURE if it Exist
return (response.StatusCode == HttpStatusCode.OK);
}
catch
{
//Any exception will returns false. So the URL is Not Exist
return false;
}
}
Hope I Helped

How do I get responseText when server sends 500 error on WebRequest.Create(URL).GetResponse()

I am calling a json web service that sends error messages by setting StatusCode to 500 and then sending error message as response text (such as { "Message": "InvalidUserName" } ).
Problem is that ASP.NET does not give me the response text if web service sends statuscode 500.
try
{
WebRequest request = WebRequest.Create(URL);
request.Method = "POST";
request.ContentType = "application/json; charset=utf-8";
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
StreamReader streamReader = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
string result = streamReader.ReadToEnd();
streamReader.Close();
response.Close();
return result;
}
catch (Exception e)
{
// If web service sends 500 error code then we end up here.
// But there is no way to get response text :-(
}
Is there a way to solve this? Also: I am controlling the web service, so it might be a solution to do some change their. (Note: I need to call the service using plain WebRequest stuff - in this case it will not work with other methods such as adding as WebReference etc)
Any ideas?
Catch WebException instead. It has a Response property containing the response. Be sure to check for null before using it.

Resources